Last modified: July 10, 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
To keep your local repository up to date with the remote repository, you can use the following Git commands:
I. Fetch:
The git fetch
command downloads the latest changes from the remote repository without integrating them into your local branch. This allows you to review the changes before deciding to merge them.
git fetch
II. Pull:
The git pull
command combines fetch
and merge
in a single step. It downloads the changes and immediately merges them into your current branch. This is useful when you want to update your branch quickly.
git pull
III. Pull with Rebase:
Sometimes, you might want to linearize the commit history by placing your changes atop those from the remote repository. This can be achieved using the git pull --rebase
command. Rebase replays your local commits on top of the fetched changes, maintaining a cleaner project history.
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 to ensure that your fork remains up-to-date with the latest changes. Here’s a detailed guide on how to keep your forked repository synchronized with the upstream repository:
I. Adding the Upstream Repository
The first step is to add the original repository, from which you forked your project, as an upstream remote repository. This is done so you can fetch changes from the original repository to keep your fork updated.
git remote add upstream original_repo_url
Replace original_repo_url
with the URL of the original repository.
II. Fetching Changes from the Upstream Repository
Fetching retrieves the latest changes from the upstream repository. This does not apply any changes to your working directory or your fork, but it updates your local copy of the upstream repository's branches.
git fetch upstream
III. Merging Changes from Upstream
After fetching the updates from the upstream repository, the next step is to merge those updates into your current branch. This applies the changes from the upstream repository’s master branch to your current branch.
git merge upstream/master
You may need to resolve any merge conflicts that arise during this step.
IV. Pushing Merged Changes to Your Remote Fork
Once you have successfully merged the changes, you need to push these changes to your forked repository on GitHub (or any other remote repository service). This ensures that your fork on the remote server is up-to-date with the upstream repository.
git push origin branch_name
Replace branch_name
with the name of the branch you are working on (e.g., main
, master
, development
).
V. Fetch and Merge in a Single Step
Alternatively, you can fetch and merge the upstream repository’s master branch into your current branch in a single step using the git pull
command. This command is a shorthand for git fetch
followed by git merge
.
git pull upstream master
This method combines the fetch and merge operations, making it quicker and easier to synchronize your fork with the upstream repository.