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:

  1. First, switch to the master branch:

git checkout master

  1. Pull the latest changes from the remote master branch to ensure you're up to date:

bash
git pull origin master

  1. 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

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:

  1. Begin by reviewing the terminal's advice. Git often provides context about the nature and location of the conflict.

  2. Use the git diff command to inspect the differences and identify the conflicting areas.

  3. Edit the affected files manually to resolve the conflicts, ensuring the desired code remains while removing Git's conflict markers (<<<<<<<, =======, >>>>>>>).

  4. Once resolved, stage the changes with git add filename.

  5. If you were in the middle of a rebase, continue the process with:

git rebase --continue

  1. Otherwise, if you were merging, finalize with a commit.
  2. Repeat the process until all conflicts are addressed.

Leveraging Git's Mergetool

To list available tools:

git mergetool --tool-help

Popular merge tools include:

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.

Table of Contents

    Syncing with a Remote Repository
    1. Retrieving Changes from the Remote Repository
      1. Fetch vs. Pull
      2. Merging a Feature Branch with the Master Branch
      3. Understanding Merging and Rebasing
    2. Understanding Merge Conflicts
      1. Steps to Resolve Conflicts
      2. Leveraging Git's Mergetool
      3. Post-Mergetool Cleanup
    3. Pushing Local Changes to a Remote Repository
    4. Keeping a Forked Repository Updated