Basic Problem
I just deleted ALL the code from a file in my project and committed the change to my local git (on purpose). I did
git pull upstream master
to fetch and merge from upstream (so in theory that deleted code should be back).
Git tells me everything is up to date.
Everything is definitely NOT up to date -- all that deleted code is still deleted.
Other Relevant Info
I only have one branch called "master".
I recently set up "master" to track upstream like so:
Branch master set up to track remote branch master from upstream.
The command git branch -vv
yields:
* master 7cfcb29 [upstream/master: ahead 9] deletion test
Why why why is this happening? I'm on the verge of just e-mailing my project manager any changes I make to our code.
Update
I thought it was obvious, but anyways this is my goal:
Get the most recent of the code on my system.
Excuse my anger here, but why does such a simple task as that have to be so hard?
As the other posters say, pull merges changes from upstream into your repository. If you want to replace what is in your repository with what is in upstream, you have several options. Off the cuff, I'd go with
Any changes you commit, like deleting all your project files, will still be in place after a pull. All a pull does is merge the latest changes from somewhere else into your own branch, and if your branch has deleted everything, then at best you'll get merge conflicts when upstream changes affect files you've deleted. So, in short, yes everything is up to date.
If you describe what outcome you'd like to have instead of "all files deleted", maybe someone can suggest an appropriate course of action.
Update:
What you don't seem to understand is that you already have the most recent code, which is yours. If what you really want is to see the most recent of someone else's work that's on the master branch, just do:
Note that this won't leave you in a position to immediately (re)start your own work. If you need to know how to undo something you've done or otherwise revert changes you or someone else have made, then please provide details. Also, consider reading up on what version control is for, since you seem to misunderstand its basic purpose.
I had the same problem as you.
I did
git status
git fetch
git pull
, but my branch was still behind to origin. I had folders and files pushed to remote and I saw the files on the web, but on my local they were missing.Finally, these commands updated all the files and folders on my local:
or if you want a branch
Someone please correct me if I'm wrong, but I believe this is because your branch is ahead of the upstream master branch by 9 commits. When you do a pull from the remote, you already have those changes, it's just that you're ahead of them by 9 commits. It wouldn't make sense for those old changes, which you already have in your history and are ahead of by 9 commits, to replace your new changes.
I believe if the commits in the remote were newer then they would be merged in (by default; unless you specify
--rebase
) to your current branch.Like Ryan said, I suggest you specify exactly what your goal is so that someone may help you more directly.
I think your basic issue here is that you're misinterpreting and/or misunderstanding what git does and why it does it.
When you clone some other repository, git makes a copy of whatever is "over there". It also takes "their" branch labels, such as
master
, and makes a copy of that label whose "full name" in your git tree is (normally)remotes/origin/master
(but in your case,remotes/upstream/master
). Most of the time you get to omit theremotes/
part too, so you can refer to that original copy asupstream/master
.If you now make and commit some change(s) to some file(s), you're the only one with those changes. Meanwhile other people may use the original repository (from which you made your clone) to make other clones and change those clones. They are the only ones with their changes, of course. Eventually though, someone may have changes they send back to the original owner (via "push" or patches or whatever).
The
git pull
command is mostly just shorthand forgit fetch
followed bygit merge
. This is important because it means you need to understand what those two operations actually do.The
git fetch
command says to go back to wherever you cloned from (or have otherwise set up as a place to fetch from) and find "new stuff someone else added or changed or removed". Those changes are copied over and applied to your copy of what you got from them earlier. They are not applied to your own work, only to theirs.The
git merge
command is more complicated and is where you are going awry. What it does, oversimplified a bit, is compare "what you changed in your copy" to "changes you fetched from someone-else and thus got added to your-copy-of-the-someone-else's-work". If your changes and their changes don't seem to conflict, themerge
operation mushes them together and gives you a "merge commit" that ties your development and their development together (though there is a very common "easy" case in which you have no changes and you get a "fast forward").The situation you're encountering now is one in which you have made changes and committed them—nine times, in fact, hence the "ahead 9"—and they have made no changes. So,
fetch
dutifully fetches nothing, and thenmerge
takes their lack-of-changes and also does nothing.What you want is to look at, or maybe even "reset" to, "their" version of the code.
If you merely want to look at it, you can simply check out that version:
That tells git that you want to move the current directory to the branch whose full name is actually
remotes/upstream/master
. You'll see their code as of the last time you rangit fetch
and got their latest code.If you want to abandon all your own changes, what you need to do is change git's idea of which revision your label,
master
, should name. Currently it names your most recent commit. If you get back onto that branch:then the
git reset
command will allow you to "move the label", as it were. The only remaining problem (assuming you're really ready to abandon everything you've don) is finding where the label should point.git log
will let you find the numeric names—those things like7cfcb29
—which are permanent (never changing) names, and there are a ridiculous number of other ways to name them, but in this case you just want the nameupstream/master
.To move the label, wiping out your own changes (any that you have committed are actually recoverable for quite a while but it's a lot harder after this so be very sure):
The
--hard
tells git to wipe out what you have been doing, move the current branch label, and then check out the given commit.It's not super-common to really want to
git reset --hard
and wipe out a bunch of work. A safer method (making it a lot easier to recover that work if you decide some of it was worthwhile after all) is to rename your existing branch:and then make a new local branch named
master
that "tracks" (I don't really like this term as I think it confuses people but that's the git term :-) ) the origin (or upstream) master:which you can then get yourself on with:
What the last three commands do (there's shortcuts to make it just two commands) is to change the name pasted on the existing label, then make a new label, then switch to it:
before doing anything:
after
git branch -m
:after
git branch -t master upstream/master
:Here
C0
is the latest commit (a complete source tree) that you got when you first did yourgit clone
. C1 through C9 are your commits.Note that if you were to
git checkout bunchofhacks
and thengit reset --hard HEAD^^
, this would change the last picture to:The reason is that
HEAD^^
names the revision two up from the head of the current branch (which just before the reset would bebunchofhacks
), andreset --hard
then moves the label. Commits C8 and C9 are now mostly invisible (you can use things like the reflog andgit fsck
to find them but it's no longer trivial). Your labels are yours to move however you like. Thefetch
command takes care of the ones that start withremotes/
. It's conventional to match "yours" with "theirs" (so if they have aremotes/origin/mauve
you'd name yoursmauve
too), but you can type in "theirs" whenever you want to name/see commits you got "from them". (Remember that "one commit" is an entire source tree. You can pick out one specific file from one commit, withgit show
for instance, if and when you want that.)The top answer is much better in terms of breadth and depth of information given, but it seems like if you wanted your problem fixed almost immediately, and don't mind trodding on some of the basic principles of version control, you could ...
Switch to master
Delete your unwanted branch. (Note: it must be have the -D, instead of the normal -d flag because your branch is many commits ahead of the master.)
Create a new branch