Axl
Axl

Reputation: 4901

Synchronizing a local Git repository with a remote one

I want to synchronize my local repository with a remote one so that my local repository becomes a 100% copy of the remote one - meaning that if certain files differ in these repositories, we override the local ones with the remote ones, and if there are files in local repositories that do not exist in the remote, the local files get removed.

Is there any way to achieve that other than by doing a fresh clone of remote repository?

Similar question as Sync local git repo with remote in one shot discarding local changes/commits.

Upvotes: 475

Views: 873418

Answers (12)

WasiF
WasiF

Reputation: 28909

If you want to sync local branches with the remote branches and remotely deleted branches should also be deleted locally then run the only command

git fetch --prune

Upvotes: 1

jobwat
jobwat

Reputation: 9263

[Edited answer] There is a few parts to consider:

While not really operating a 'full sync' with the remote, the following will probably achieve what you need.

Note: you may lose local changes.

The Branch references

When fetching from a repository, the new (remote) references are synced up automatically but the old ones aren't cleaned out from the local. The purge option fixes that. [original answer]

git fetch --prune

-p, --prune
Before fetching, remove any remote-tracking references that no longer exist on the remote. git fetch prune option doc on git-scm

The pull command also has the prune option (--prune or -p) see git-scm doc

git pull -p

The commits

All local branches could potentially be out of sync.

To sync up the current branch with the remote, and potentially lose local work, reset it to the remote position:

git reset --hard origin/<current_branch_name>

Again, caution: this would clear out the local changes (non-committed changes & non-pushed commits).

Note: This would have left 'un-synced' any other branch.

The files/changes

The not staged for commit changes

These would have been removed by the above git reset --hard

The untracked files

These can be cleaned out using

git clean -f -d

Note that you may lose some local work.

The ignored files

Some files are declared to be ignored (via .gitignore files) and become hidden to the git tracking.

To clean them out, run:

git clean -f -d -x

Note that the git clean command comes with a handy dry-run option to avoid making that mistake a little too fast:

git clean -f -d -x -n

-n, --dry-run

Don’t actually remove anything, just show what would be done.


As the top-rated answer, I felt compelled to revisit my not really answering former reply. Thanks to the comments and other answers which helped me form a better reply.

Upvotes: 607

Asaf
Asaf

Reputation: 1261

This script will check what local remotes do not exist in your remote and remove them from local

git fetch --prune; git branch -vv | egrep -v "(\[origin\/[a-zA-Z0-9/_-]+\])" | awk "{print \$1}" | xargs git branch -D

Upvotes: 5

monkSinha
monkSinha

Reputation: 361

The permanent fix if one wants to create a new branch on the remote to mirror and track your local branch(or, vice-versa) is:

git config --global push.default current

I always configure my local git with this command after I do git clone. Although it can be applied anytime when the local-remote branch "Git fatal: The current branch has no upstream branch" error occurs.

Upvotes: 2

aandis
aandis

Reputation: 4222

You want to do

git fetch --prune origin
git reset --hard origin/master
git clean -f -d

This makes your local repo exactly like your remote repo.

Remember to replace origin and master with the remote and branch that you want to synchronize with.

Upvotes: 185

Mahendra Pratap
Mahendra Pratap

Reputation: 3633

Reset and sync local repository with remote branch

The command: Remember to replace origin and master with the remote and branch that you want to synchronize with.

git fetch origin && git reset --hard origin/master && git clean -f -d

Or step-by-step:

git fetch origin
git reset --hard origin/master
git clean -f -d

Your local branch is now an exact copy (commits and all) of the remote branch.

Command output:

Here is an example of running the command on a local clone of the Forge a git repository.

sharkbook:forge lbaxter$ git fetch origin && git reset --hard origin/master && git clean -f -d
HEAD is now at 356cd85 FORGE-680
Removing forge-example-plugin/
Removing plugin-container-api/
Removing plugin-container/
Removing shell/.forge_settings
sharkbook:forge lbaxter$

Upvotes: 22

FractalSpace
FractalSpace

Reputation: 5685

These steps will do it:

git reset --hard HEAD
git clean -f -x -d -n

then without -n

This will take care of all local changes. Now the commits...

git status

and note the line such as:

Your branch is ahead of 'xxxx' by N commits.

Take a note of number 'N' now:

git reset --hard HEAD~N
git pull

and finally:

git status

should show nothing to add/commit. All clean.

However, a fresh clone can do the same (but is much slow).

===Updated===

As my git knowledge slightly improved over the the time, I have come up with yet another simpler way to do the same. Here is how (#with explanation). While in your working branch:

git fetch # This updates 'remote' portion of local repo. 
git reset --hard origin/<your-working-branch>
# this will sync your local copy with remote content, discarding any committed
# or uncommitted changes.

Although your local commits and changes will disappear from sight after this, it is possible to recover committed changes, if necessary.

Upvotes: 202

Nishant Upadhyay
Nishant Upadhyay

Reputation: 639

If you are talking about syncing a forked repo then you can follow these steps.

How to sync a fork repository from git

  1. check your current git branch

    git branch

  2. checkout to master if you are not on master

    git checkout master

  3. Fetch the upstream repository if you have correct access rights

    git fetch upstream

  4. If you are getting below error then run

    git remote add upstream [email protected]:upstream_clone_repo_url/xyz.git

    fatal: 'upstream/master' does not appear to be a git repository  
    fatal: Could not read from remote repository.
    Please make sure you have the correct access rights and the repository exists.
    
  5. Now run the below command.

    git fetch upstream

  6. Now if you are on master then merge the upstream/master into master branch

    git merge upstream/master

    That's it!!

    Crosscheck via git remote command, more specific git remote -v

    If I also have commit rights to the upstream repo, I can create a local upstream branch and do work that will go upstream there.

Upvotes: 4

tjb
tjb

Reputation: 11728

(This info is from The Git User's Manual)

I'm also learning, so this might not be exactly an answer to the question but it might help somebody:

  1. When a remote repository is initially cloned copies of all branches are stored in your local repository (view them with git branch -r)
  2. To update these copies and make them current (i.e. sync them with the remote branch) use git fetch. This will not effect any of you existing, custom created branches.
  3. To override your local branch checkout a fresh version of whatever branch you are working on (Assuming that you have already executed git add origin /path/to/repository) use git checkout origin/branch_name, this will override your locals changes on branch branch_name

Upvotes: 5

Paŭlo Ebermann
Paŭlo Ebermann

Reputation: 74800

You need to understand that a Git repository is not just a tree of directories and files, but also stores a history of those trees - which might contain branches and merges.

When fetching from a repository, you will copy all or some of the branches there to your repository. These are then in your repository as "remote tracking branches", e.g. branches named like remotes/origin/master or such.

Fetching new commits from the remote repository will not change anything about your local working copy.

Your working copy has normally a commit checked out, called HEAD. This commit is usually the tip of one of your local branches.

I think you want to update your local branch (or maybe all the local branches?) to the corresponding remote branch, and then check out the latest branch.

To avoid any conflicts with your working copy (which might have local changes), you first clean everything which is not versioned (using git clean). Then you check out the local branch corresponding to the remote branch you want to update to, and use git reset to switch it to the fetched remote branch. (git pull will incorporate all updates of the remote branch in your local one, which might do the same, or create a merge commit if you have local commits.)

(But then you will really lose any local changes - both in working copy and local commits. Make sure that you really want this - otherwise better use a new branch, this saves your local commits. And use git stash to save changes which are not yet committed.)


Edit: If you have only one local branch and are tracking one remote branch, all you need to do is

git pull

from inside the working directory.

This will fetch the current version of all tracked remote branches and update the current branch (and the working directory) to the current version of the remote branch it is tracking.

Upvotes: 100

Richard Hansen
Richard Hansen

Reputation: 54253

Sounds like you want a mirror of the remote repository:

git clone --mirror url://to/remote.git local.git

That command creates a bare repository. If you don't want a bare repository, things get more complicated.

Upvotes: 3

Makis
Makis

Reputation: 12988

You can use git hooks for that. Just create a hook that pushes changed to the other repo after an update.

Of course you might get merge conflicts so you have to figure how to deal with them.

Upvotes: -3

Related Questions