Introduction
We are going to cover some of the challenges that occur when using git version control during the software development process.
They include:
How to resolve a merge conflict
How to rename master branch to main
How to undo pushed commits
How to co-author commits
How to resolve a merge conflict
A merge conflict occurs when there is/are conflicting change(s) made on different or the same files from the main branch or different branches. To resolve a merge conflict you have to accept changes to incorporate from different branches in a new commit.
We will cover how to solve this on the command line:
Open the command line and navigate to the local repository that has a merge conflict
Get a list of files affected by the merge conflict. In this example the file example.md has a merge conflict:
$ git status
> # On branch example-b
> # You have unmerged paths.
> # (fix conflicts and run "git commit")
> #
> # Unmerged paths:
> # (use "git add <file>..." to mark resolution)
> #
> # both modified: example.md
> #
> no changes added to commit (use "git add" and/or "git commit -a")
Open your favorite text editor and navigate to the file that has a merge conflict
To find where a merge conflict has occurred in your file, search for the following markers
<<<<<<<
. In your file, you will see changes fromHEAD
or base branch after the line<<<<<<< HEAD
. Next, you will see======
that separates changes from other branches, followed by>>>>>> BRANCH-NAME
. In this example, one person wrote "Git is a version control software" in the base orHEAD
branch and another person wrote "you need to install." in the compare branch orexample-a
.
Changes made
<<<<<<< HEAD
Git is a version control software
=======
you need to install.
>>>>>>> example-a
- Decide on the changes you want to keep then delete the conflict markers
<<<<<<<
,=======
,>>>>>>>
. Make changes you want in the final merge. In our example, we incorporate both changes:
Git is a version control software which you need to install on your local system in order to use it
- Add or stage your changes.
git add .
- Commit you changes
git commit -m "Resolved merge conflict by incorporating both suggestions."
- Finally, push your changes
git push
Removed file merge conflicts
This occurs when there are competing changes to a file. For example, if a person deletes a file in one branch and another person edits the same file, you must choose whether to delete or keep the removed file in a new commit.
Open Terminal. Navigate into the local Git repository that has the merge conflict.
Get a list of files affected by a merge conflict. In this example, the file README.md has a merge conflict.
$ git status > # On branch main > # Your branch and 'origin/main' have diverged, > # and have 1 and 2 different commits each, respectively. > # (use "git pull" to merge the remote branch into yours) > # You have unmerged paths. > # (fix conflicts and run "git commit") > # > # Unmerged paths: > # (use "git add/rm <file>..." as appropriate to mark resolution) > # > # deleted by us: README.md > # > # no changes added to commit (use "git add" and/or "git commit -a")
Open your favorite text editor and navigate to the file that has merge conflicts.
Decide if you want to keep the removed file. You may want to view the latest changes made to the removed file in your text editor.
To add the removed file back to the repository:
git add README.md
To remove this file from the repository:
$ git rm README.md
> README.md: needs merge
> rm 'README.md'
- Commit your changes.
$ git commit -m "Resolved merge conflict by keeping README.md file."
- Push your changes.
git push
How to rename master branch to main
The default branch in most Git repositories was named "master". Fortunately, many people have become aware that this terminology should be replaced as the tech industry moves to a more inclusive, open culture - and removing language like "master/slave" is an important step in this journey.
Several alternatives for "master" have come up, "default" and "primary" being some of them. But the most popular term seems to be "main".
To rename your branch to main follow these steps:
- Checkout the
master
branch :
git checkout master
# Make sure you have the latest changes
git pull origin master
- Rename the local branch with the following command:
git branch -m main
- Note that this change is only in your local repository, what you need to do next is to push this the remote, using this command:
git push origin -u main
Change the default branch
At this point, you have both master
and main
on your remote, and before you can delete the master
branch, you need to go to the repository settings on your Github account, On the General
section, scroll to Default branch
then click on the pen icon. If it’s master
you should change it to your new main
branch
Once you have switched the default branch, you can safely delete the remote master
branch:
git push origin --delete master
How to undo pushed commits
Ever made a commit or checked your commit history and thought "Oops! My commit history is wanting!". Git provides various ways to undo pushed commits.
Method 1: Reverting a Commit
This is a great method, especially if you're working in a team. Reverting doesn't delete any commits; it adds a new commit that undoes the changes.
Single Commit
# Show commit history
git log
# commit <commit-hash>
# Create a new commit that undoes the previous one
git revert <commit-hash>
# Push the new commit
git push
Before pushing, consider creating a new branch and running your tests. It's just safer that way.
Multiple Commits
# Show commit history
git log
# commit <commit-hash>
# Revert a range of commits
git revert OLDEST_COMMIT_HASH^..NEWEST_COMMIT_HASH
# Push the new commits
git push
Method 2: Resetting a Commit
Use this when you absolutely need to, because it rewrites commit history.
# Show commit history
git log
# commit <commit-hash>
# Move the HEAD and branch pointer to a specific commit
git reset --hard <commit-hash>
# Force push to apply the changes to the remote repository
git push --force-with-lease
Note: Coordinate with your team before using
--force-with-lease
, or you risk causing mayhem.
Method 3: Interactive Rebase
This method is complex however it gives you the most control.
# Show commit history
git log
# commit <commit-hash>
# Start an interactive rebase
git rebase -i <commit-hash>^
# Vim (or your default editor) will open. Make your changes.
# Save and exit the editor.
# Force push the changes
git push --force-with-lease
Note: Don't do this on shared branches without coordinating with your team.
How to co-author commits
When you are pair programming (or if someone's been helpful to you), you may want to be able to give them credit in a commit you make in a Git repository.
To achieve this from the command line, you just have to add this to your commit message:
Co-authored-by: name <someemail@example.com>
In a situation where you don't know that person's email address configured in Git, you can just run
git log
and then scroll through until you find it (which works well on small teams or when that person has a branch that you can check out and run this on). You could also get a bit more adventurous and run
git show <commit-hash> --format=email
to get just their email. Or you can be less adventurous and just ask them.
This is fairly easy to do, but in case you like to use the command line, this is how you'd write it:
git commit -m "Regular commit message" -m "Co-authored-by: name <someemail@example.com>"
And then, once you push, GitHub will credit that person with the commit alongside you!
Happy coding!