tags:

views:

49

answers:

2

Coming from an svn background, I had this question:

http://stackoverflow.com/questions/1138990/git-equivalent-of-svn-status-u

(what is the git equivalent of svn status -u)

And I understand, you do:

git fetch
git log ..origin/master

But, I'm guessing the origin/master part depends on the branch? It wouldn't necessarily be master if I was tracking a remote branch?

I also don't understand the git merge origin/master precisely. I'm guessing that just means that git fetch grabbed the changes from the remote and put them into the git database system as origin/master and I'm in just master? What if I fetched changes, check what was done, am horrified by the changes and don't want to merge? How do I basically abandon them?

A: 

git fetch downloads all the changes needed to represent the given remote branch. Typically this is origin/master or similar.

git merge merges two branches together by creating new commits or fast-forwarding (or a combination). It doesn't change any commits you have made, and you can always roll back to your old branch (using git reset or git checkout).

Note that git pull is git fetch followed by git merge (or git rebase if --rebase is given).

strager
Is origin/master just a reference to unmerged information on the local machine? It's not "origin" as in something remote?
Hans
How do you abandon fetched changes if you decide not to merge them?
Hans
@Hans, There's no need to 'abandon' changes; just don't reference them. If you want to reset the local `origin/master` reference for whatever reason, use `git reset`. What are you trying to accomplish? (An SVN analogy is fine.)
strager
@Hans: Correct: origin/master is a local reference to a local copy of where origin's master was when you fetched. (It's called a remote branch.) If you don't want to merge it, don't merge it.
Jefromi
@strager (thanks) I'm just thinking that if I pull from someone, check out the changes, then decide against them, but want to pull again, then I'll eventually have to merge them? I can see "git branch -d" for a topic branch or something but what if someone does something in origin/master I want to eliminate?
Hans
I think I'm probably overthinking this. @strager made me thing when he said "an svn analogy is fine" and I couldn't come up with one. Though git seems to have a lot of features and buzz, when I started using svn it all made immediate sense to me, but git doesn't.
Hans
@Hans, I suggest you go on Youtube and watch the couple of talks on Git. They helped me understand Git better.
strager
+1  A: 

git fetch

git fetch grabs changes from remote repository and puts it in your repository's object database. It also fetches branches from remote repository and stores them as remote-tracking branches.

When you are fetching git tells you where it stores each branch on remote repository it fetches. For example you should see something like

   7987baa..2086e7b  master -> origin/master

when fetching. This means that 'origin/master' stores where 'master' is on 'origin' repository.

If you examine .git/config file, you would see the following fragment:

[remote "origin"]
        url = git://git.example.com/repo.git
        fetch = +refs/heads/*:refs/remotes/origin/*

This (among others) means that any branch 'A' ('refs/heads/A') in origin remote (repository you cloned from) would be saved as 'origin/A' ('refs/remotes/origin/A').

git log ..origin/master

As you can see 'origin/master' is 'master' in origin. If you are on (default) 'master' branch, then git log ..origin/master, which is equivalent to git log HEAD..origin/master, which when on 'master' branch is equivalent to git log master..origin/master would list all commits that are on 'master' branch in remote repository and are not in local 'master' branch where you do your work.

The more generic version in modern git (assuming that upstream / tracking information exists) would be to use simply

$ git log ..@{u}

(Here @{u} is synonym for @{upstream}, see gitrevisions manpage).

git merge origin/master

git merge is used to join two lines of history. If one of sides didn't do any work since last branching point (since merge base), the situation is either fast-forward (the branch you are on is simply updated to the tip of the branch you are merging), or up-to-date (there is nothing new to merge, and the branch you are on stays unchanged).

git fetch followed by git merge origin/master, when on 'master' branch, is equivalent to issuing

$ git pull

If you don't want to merge, you don't need to. Note that you can use e.g. git reset --hard HEAD@{1} to go back and discard result of git pull if you don't like it.

Jakub Narębski
This clears up a lot, thanks Jakub; but, say I fetch from the remote, now origin/master has some changes, I "git log ..origin/master" to see what has been done but I don't want it. If I ever want to merge again, I have to have whomever made the change revert it first, then right? I guess I could co a file from a previous commit, too, right? Something to get rid of it so I can merge again.
Hans
@Hans: Right. What's in 'origin/master' isn't yours, but it tracks development in 'origin' repository. It is best if development is done using **feature branches**, which can be merged or not, and not directly on trunk (in 'master'); this I think requires agreement *who of you is a maintainer* and is to merge changess in. To avoid merging in changes from 'origin/master' you can do '--strategy=ours' merge, which creates merge commit but takes your result; it saves 'origin/master' in history, but practically *discards* its result.
Jakub Narębski