Last modified: June 11, 2024
This article is written in: 🇺🇸
Syncing with a Remote Repository
When collaborating on a project, it's essential to keep your local repository updated with changes made by others in the team. Git provides powerful commands to facilitate this process.
Retrieving Changes from the Remote Repository
- Fetch: This command downloads the latest changes from the remote repository without integrating them into your local branch. It is particularly useful if you want to see the changes before deciding to merge them.
git fetch
- Pull: Unlike fetch, the pull command not only fetches the changes but also merges them into your current branch. This is a two-step process rolled into one command.
git pull
- Pull with Rebase: Sometimes, you might want to linearize the commit history by placing your changes atop those from the remote. This can be achieved using:
git pull --rebase
Fetch vs. Pull
Action | Fetch | Pull |
Purpose | Downloads updates from the remote but leaves your local branch untouched. | Directly integrates the fetched changes into your current branch. |
Provides flexibility as you decide when to integrate those changes. | Essentially a combination of fetch and merge. |
After fetching, if you decide to integrate the changes, you can either:
Use the merge command:
git fetch
git merge
Or, if you want to override local changes to match the state of the remote branch, employ:
git fetch
git reset --hard origin/branch_name
Note: Ensure any pending work is committed before using reset to avoid potential data loss.
Merging a Feature Branch with the Master Branch
Suppose you've been developing a new feature on a branch called feature_branch
. Once you're ready to integrate this feature with the master
branch, follow these steps:
- First, switch to the
master
branch:
git checkout master
- Pull the latest changes from the remote master branch to ensure you're up to date:
bash
git pull origin master
- Merge your feature_branch into the master:
git merge feature_branch
Understanding Merging and Rebasing
When it comes to integrating changes from one branch into another, Git offers two primary strategies:
Aspect | Merging | Rebasing |
Process | Combines changes into a new commit | Moves commit history onto target branch |
Commit History | Retains individual commit history of both branches | Provides a cleaner, linear commit history |
Collaboration | Creates a unique commit referencing merged branches | Rewrites history, potential collaboration issues |
Understanding Merge Conflicts
- Merge conflicts typically occur in a collaborative coding environment, especially when changes happen in close proximity within a file.
- Manual intervention is needed to decide which code changes to retain and which to discard.
- While distinct code changes might not physically clash, they can still be conceptually conflicting, requiring careful review.
Master Branch: Feature Branch:
+---------------------------+ +---------------------------+
| | | |
| some code... | | some code... |
| | | |
| ++++++++++++ | | ++++++++++++ |
| | | |
| the conflicting line | | the alternate line |
| | | |
| ++++++++++++ | | ++++++++++++ |
| | | |
| more code... | | more code... |
| | | |
+---------------------------+ +---------------------------+
Attempt to Merge:
+-------------------------------------+
| |
| some code... |
| |
| <<<<<<< HEAD |
| the conflicting line |
| ======= |
| the alternate line |
| >>>>>>> feature-branch |
| |
| more code... |
| |
+-------------------------------------+
Steps to Resolve Conflicts
If you encounter merge conflicts:
-
Begin by reviewing the terminal's advice. Git often provides context about the nature and location of the conflict.
-
Use the
git diff
command to inspect the differences and identify the conflicting areas. -
Edit the affected files manually to resolve the conflicts, ensuring the desired code remains while removing Git's conflict markers (
<<<<<<<
,=======
,>>>>>>>
). -
Once resolved, stage the changes with
git add filename
. -
If you were in the middle of a rebase, continue the process with:
git rebase --continue
- Otherwise, if you were merging, finalize with a commit.
- Repeat the process until all conflicts are addressed.
Leveraging Git's Mergetool
- Git provides a mergetool command, which is an interactive interface to aid conflict resolution.
- By default, it uses Vimdiff for visual comparison. However, numerous other editors are supported.
To list available tools:
git mergetool --tool-help
Popular merge tools include:
- kdiff3
- meld
- tortoisemerge
Switching to another tool, e.g., meld:
git config --global merge.tool meld
To use mergetool when a conflict arises:
git mergetool
This displays a three-panel view for each conflicted file: - Left: Your local changes - Center: Merged result - Right: Remote changes
Make resolutions in the center panel, save, and exit the editor.
Post-Mergetool Cleanup
After using mergetool, you might notice .orig
files. These backups are created during conflict resolution.
To remove these backups:
git clean -i
To prevent creation of these backup files in future:
git config --global mergetool.keepBackup false
Remember, understanding the context of the changes and frequent communication with collaborators can significantly reduce the likelihood and complexity of merge conflicts.
Pushing Local Changes to a Remote Repository
To push local branch changes to the remote repository:
git push origin branch_name
Ensure you replace branch_name with the actual name of your branch.
Note: This will work if the remote branch has no new commits since you last synchronized. If there are newer commits, you'd have to first merge or rebase with the remote branch.
For pushing a new branch and setting up tracking:
git push -u origin branch_name
This not only creates the branch remotely but also establishes a tracking relationship.
Force Pushing: Sometimes, you may need to forcefully push changes, overriding any conflicting changes on the remote. This can be done using:
git push --force origin branch_name
Warning: Use --force
carefully, as it can discard remote changes and lead to data loss.
Keeping a Forked Repository Updated
When working with forked repositories, it's common to want to synchronize your fork with the original (or "upstream") repository:
- First, ensure you've added the original repository as an upstream:
git remote add upstream original_repo_url
- Fetch the changes from the upstream repository:
git fetch upstream
- Merge the changes from the upstream's master branch into your current branch:
git merge upstream/master
- Push these merged changes to your remote fork:
git push origin branch_name
- Alternatively, you can fetch and merge in a single step using:
git pull upstream master