Avoiding Merge Conflicts
1. Essential workflow
-
Clone your fork of the upstream repository you will be contributing to:
$ git clone <address_of_your_fork>
-
Change your working directory to the generated local copy.
-
Create a remote for the upstream of your fork:
$ git remote add upstream <address_of_upstream_repository>
-
Pull any upstream changes and rebase based on upstream’s
master
branch:$ git pull --rebase upstream master
Note-
This command will pull all of the upstream changes, apply them, then replay your local commits back on top of the updated branch contents.
-
You should run
git pull --rebase upstream master
any time changes are committed to the upstream repository. Ensuring that you are using the latest upstreammaster
branch will prevent issues which occur due to using an old version of themaster
branch.
-
-
Create your topic branch based on the latest upstream
master
:$ git checkout -b <topic_branch>
NoteWhen creating a new branch, the branch will be based on the content of the current branch. Ensure that you are on the
master
branch and have any recent upstream changes pulled and rebased before creating your topic branch. This will prevent issues and merge conflicts which occur due to using an old version of themaster
branch. -
Make small, atomic changes to the content for your topic branch. Only commit the changes once you are certain that your changes are complete:
$ git add --all $ git commit -m "<commit_message>"
Note-
You may need to switch branches before your work is entirely ready to commit. To do this cleanly, see Using the stash.
-
You should ensure that your changes are small and atomic so that your commit is as focused as possible. A focused commit will only touch the information relevant to it. A smaller affected surface means less opportunities for merge conflicts.
-
2. Pull request workflow
-
If changes are requested on your pull request, you can amend this commit and force-push the changes to your fork:
$ git add --all $ git commit --amend $ git push --force origin <topic_branch>
NoteAmending the commit and force-pushing to your fork will update the pull request with your changes while ensuring you only add a single commit to the repository. This helps keep the Git history clean while avoiding potential merge conflicts for others in the future.
3. Using the stash
You may need to switch branches in your local repository before the changes you have made are ready to commit.
In this case, git
will report an error when you attempt to switch branches due to the current status not being in a clean state.
The git stash
command provides a way to ensure a clean Git state while preserving your in-progress changes.
3.1. Stashing changes
To preserve your in-progress edits while keeping the Git state clean, use the following command:
$ git stash
This command will stash your changes away and return Git to a clean state. You can now safely switch to the required branch.
3.2. Restoring stashed changes
Once you are done with the work required on a different branch, checkout the branch you were previously working on and use the following command to restore your previous edits:
$ git stash pop
3.3. Listing stashed changes
If you have more than one set of changes stashed, you can view the contents of your stash with the following command:
$ git stash list
4. Using visual tools
Git allows you to define visual tools for working with diffs and merges. Meld is a recommended choice.
To install Meld on Fedora, use the following command:
$ sudo dnf install meld
4.1. Configuring the diff tool
To configure Meld as your diff tool, add the following to your ~/.gitconfig
file:
[diff] tool = meld [difftool] prompt = false [difftool "meld"] cmd = meld "$LOCAL" "$REMOTE"
Use the configured visual diff tool with the following command:
$ git difftool
Note
|
The diff tool does not replace the functionality of the |
4.2. Configuring the merge tool
To configure Meld as your merge tool, add the following to your ~/.gitconfig
file:
[merge] tool = meld [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
Use the configured visual merge tool with the following command:
$ git mergetool
Note
|
|
5. Miscellaneous advice
-
Know who is working on what and when.
-
This is the primary social aspect of what causes the majority of the remaining merge conflicts you are likely to encounter. By knowing who is working on a specific section at a specific time, you can ensure that no one else works on the same content while their work is in progress.
-
-
Be vigilant about the status of the Git repository.
-
Use
git status
often. -
Make sure that your Git repository is as up-to-date as possible with the upstream repository.
-
Before beginning new work, checkout your
master
branch, pull and rebase from the upstream repository’smaster
branch, then create your topic branch.
-
-
(Optional) Use one line per sentence when writing in AsciiDoc.
-
Using one line per sentence makes
git
logs and diffs cleaner. This practice also ensures that no merge conflicts will occur if two separate sentences are changed within a single paragraph. -
AsciiDoc still renders sentences on individual lines as coherent paragraphs until two new lines are encountered in a row.
-
6. Condensed workflows
6.1. Essential workflow
git clone <address_of_your_fork> cd <repository_directory> git remote add upstream <address_of_upstream_repository> git checkout master git pull -r upstream master git checkout -b <topic_branch> git add ... git commit -m "<commit_message>"
6.2. Pull request workflow
git checkout <topic_branch> git pull -r upstream master git add ... git commit --amend git push -f origin <topic_branch>