Reputation: 35
While on my master branch I did a "git fetch" for another branch.
How do I undo that?
My question is strictly about git fetch, and what operation is needed to undo it and then if possible verify that the local repo branch matches the remote repo branch. The answer I'm looking for will shed some light on what exactly git fetch is downloading into the repo. My first assumption is that it's only downloading and updating data in the repo's .git directory. What I would really like to know is, is "git fetch" completely overwriting data that it downloads for a branch (and so would then match the remote branch perfectly) or does it update with remote change/delta data into the my local repo?
For additional clarification: I'll call the other branch, "devbranch". The problem was; instead of first switching git to the devbranch and then fetching devbranch, I fetched devbranch into the master branch.
If I just do "git fetch" on master does that overwrite the devbranch fetch I did on master or does it just add to the mess on my master branch? Or should I do something like (git reset --hard HEAD).
Thank you for you help.
= = = = = = = = = = = =
Editing after several comments:
[--1--] Most importantly I'm trying to understand exactly what "git fetch" does. My initial question explains what caused me to realize I don't really understanding it very well. If you can explain what "git fetch" updates in a repo, please do, thanks. And more important, does a subsequent fetch just overwrite the previous fetch?
[--2--] Assuming we all agree that "git fetch" does in fact add or update something into a local repo from the remote (not the local files but in the .git directory) -and- that not specifying the correct branch or being switched to the correct branch (e.g. like in my initial question) that it could(?) cause something to get corrupted if a "git merge" is applied. How then does someone undo a fetch.
Would a second "git fetch" on the correct branch and with the correct branch specified do the trick? e.g. * git checkout * git fetch origin
The text from the following git manual page talks about specifying a branch on the command. Also note that the fetch command has a "--dry-run" implying that something is getting updated. It seems to me that it's pretty important to know what is getting updated and how to undo a fetch made on the wrong branch. What am I missing, Thank for your help.
http://git-scm.com/docs/git-fetch
When no remote is specified, by default the origin remote will be used, unless there’s an upstream branch configured for the current branch.
--dry-run Show what would be done, without making any changes.
Upvotes: 1
Views: 1958
Reputation: 165268
Assuming we all agree that "git fetch" does in fact add or update something into a local repo from the remote (not the local files but in the .git directory) -and- that not specifying the correct branch or being switched to the correct branch (e.g. like in my initial question) that it could(?) cause something to get corrupted if a "git merge" is applied. How then does someone undo a fetch.
This mixes up fetching and merging. There is no danger running git fetch
even if you specify the wrong branch. I would advise you don't bother fetching specific branches and just git fetch
everything. It's simpler, safe, and unless your repository has lots of enormous branches it's efficient.
However, merging the wrong branch is a problem. It won't "corrupt" anything in the sense that the repository isn't broken, but you'll end up with the wrong code and probably a lot of conflicts. Fortunately, a bad merge can be undone.
Fetching and merging as two separate steps and specifying the branch to be fetched and merged is unnecessary and leads to exactly the sort of mistake you've made. It's simpler to just git pull
(which is fetch + merge) and let Git figure out what to fetch and merge. Git has a concept of a tracking branch which is what remote branch to merge with when git pull
is run. For example, master
normally tracks origin/master
. When you run git pull
, Git will fetch and then merge with the current branch's tracking branch. This avoids mistakenly merging with the wrong branch.
git fetch
does these things.
origin/blah
) to match.git fetch
does not change any of your local branches. This is why running git fetch
is usually harmless and there's little need to undo it.
For example, let's say you had this...
LOCAL
A - B - C - D - E [origin/master] - H - I [master]
\
F - G [my-branch]
ORIGIN
3 - 4 [origin/other-branch]
/
A - B - C - D - E - 1 - 2 [master]
After running git fetch
you'd have this.
LOCAL
3 - 4 [origin/other-branch]
/
1 - 2 [origin/master]
/
A - B - C - D - E - H - I [master]
\
F - G [my-branch]
ORIGIN
3 - 4 [other-branch]
/
A - B - C - D - E - 1 - 2 [master]
Your local branches remain unchanged. Git only added new commits and moved (or added) remote branches. None of your local branches are affected. master
and mybranch
stay where they are. There's no merging or fast-forwarding or rebasing done. That all happens as part of a git-pull
. A pull
is really just a fetch
plus a merge
.
git-fetch
went something like this...
master
is at commit 2.
origin/master
to commit 2.other-branch
at commit 4.
origin/other-branch
at commit 4.This is known as "the dumb protocol". Most Git installations use a much more efficient technique called "the smart protocol" which reduces the number of queries by doing most of the work of figuring out what commits need to be fetched on the server side and delivering them in bulk. Git will only use the dumb protocol when it's using a server with no special Git support, such as a plain HTTP server. The dumb protocol is still useful for understanding what's going on.
There is no single command to undo a git-fetch
, but you can move origin/master
back to its previous location using the technique in this answer to manually move references around.
git update-ref refs/remotes/origin/master refs/remotes/origin/master@{1}
Git maintains a history of branch locations (branches are just labels on commits) using the branch@{#}
syntax. origin/master@{1}
is the previous location of origin/master
.
Upvotes: 3
Reputation: 96554
Git fetch only affects the "remote" branches that are held locally.
This concept leads to a great deal of confusion.
It is important to understand that there are 4 main "places" where your code is stored:
.git/
(Your 'index')..git/
(Your local repository)..git
directory, with files just placed in the top-level directory where the working directory would normally be.So when you do a fetch you are updating 3)
When you do a pull on the other hand, those branches are:
retrieved from the remote to your local repository(3) placed (or updated) in your local branches (2) processed to get the actual files in the commit created or updated locally o your file system.
You may find that https://stackoverflow.com/a/9204499/631619 is helpful
The fears you have are more appropriate for git pull
where, if you are in a different branch, you can accidentally merge in code from the wrong branch. I have done that.
Upvotes: 3