new to git
After many years of dissatisfaction with the limitations of CVS, and after getting fed up with the complexity of configuring and maintaining a SVN setup, I just started using git for my own personal projects. I have to say it's quite nice and fits the UNIX philosophy well: fast, simple, powerful.
I've been playing with it for a few weeks and generally understand what is going on, but I do have a few usage questions that I couldn't find answered in the docs:
(1) Let's say I:
git clone something
git branch foo
git checkout foo
<make some changes>
git commit -a
git checkout master
git pull . foo
git push
git pull
what is actually happening? The pull appears to do something (i.e., I get:
* refs/remotes/origin/master: fast forward to branch 'master' of /home/krose/git-repository/baz/
old..new: 7cf088c..d344f98
), but makes no changes locally since I have the latest revision. Another subsequent git pull does, in fact, say everything is up to date.
(2) Any way to disable this warning:
Warning: No merge candidate found because value of config option
"branch.local.merge" does not match any remote branch fetched.
(3) I notice I can't reset --hard a single file. So, if I want to revert a single file to some revision, blowing away my changes, what is the accepted way of doing this? Is there a way to do the equivalent of a p4 print foo@some_revision?
(4) I'm still not clear on when a dst should and should not be used in a refspec. It appears that one can only do non-fast forward updates to the branch that is checked out (which makes sense, since you may need to resolve), but other than that, what is the difference between
git checkout foo
git pull . master
and
git checkout master
git push . master:foo
?
(5) Are there any tools for managing some of the metadata (e.g., the origin URL) or is it expected that one edit it directly?
Thanks for all your work on this: git fills a need I didn't know I had until I actually found myself using it: a completely decentralized patch management system.
Kyle
Quoted 3 lines · Kyle Rose
I've been playing with it for a few weeks and generally understand what is going on, but I do have a few usage questions that I couldn't find answered in the docs:
I think I tried to cover most of this in the user-manual
(http://www.kernel.org/pub/software/scm/git/docs/user-manual.html has the latest version, or it's in Documentation/) but some of it may be harder to find than it should be.
Quoted 12 lines
(1) Let's say I:
git clone something
git branch foo
git checkout foo
<make some changes>
git commit -a
git checkout master
git pull . foo
git push
git pull
Quoted 5 lines
what is actually happening? The pull appears to do something (i.e., I get:
* refs/remotes/origin/master: fast forward to branch 'master' of
/home/krose/git-repository/baz/
old..new: 7cf088c..d344f98
Git caches the value of the remote's "master" in refs/remotes/origin/master. That's the thing that's getting updated; you can actually
cat .git/refs/remotes/origin/master
before and after you'll see that it got updated from 7cf088c to d344498.
I think newer versions of git actually update that "remote-tracking branch head" on the push as well, which would prevent you from getting the message since by the time of the pull that thing will already have been updated.
Quoted 3 lines
(3) I notice I can't reset --hard a single file. So, if I want to revert a single file to some revision, blowing away my changes, what is the accepted way of doing this?
git checkout some_revision path/to/filename
Quoted 2 lines
Is there a way to do the equivalent of
a p4 print foo@some_revision?
I don't know p4, but maybe you're looking for
git show some_revision:foo
Quoted 5 lines
(4) I'm still not clear on when a dst should and should not be used in a refspec. It appears that one can only do non-fast forward updates to the branch that is checked out (which makes sense, since you may need to resolve), but other than that, what is the difference between
Quoted 7 lines
git checkout foo
git pull . masterand
git checkout master
git push . master:foo
The latter should forcibly reset the branch head "foo" to point at the same commit as "master". The former tries to do a merge between the two.
In the case where master is a descendant of foo (so there's no commits in foo that isn't already in master), the two should do the same thing.
Quoted 2 lines
(5) Are there any tools for managing some of the metadata (e.g., the origin URL) or is it expected that one edit it directly?
Maybe you want "man git-remote"? Or see "git-config" for more general configuration.
But editing .git/config file directly is often simplest, and won't cause any problem.
--b.
First of all, welcome to git :)
Having been away from the mailing list for too long, I can't answer all your questions. I'll take a stab at the ones I've got a clue about though.
I also recommend that you upgrade your git installation to at least 1.5.3, as most of the people figuring on this list will most likely give advice that matches that version.
For reference, the git documentation can be found at
http://www.kernel.org/pub/software/scm/git/docs/
J. Bruce Fields et al have written some really excellent introductory documents which are a must to anyone who wishes to flatten the initial learning curve a bit.
Quoted 22 lines · Kyle Rose
After many years of dissatisfaction with the limitations of CVS, and after getting fed up with the complexity of configuring and maintaining a SVN setup, I just started using git for my own personal projects. I have to say it's quite nice and fits the UNIX philosophy well: fast, simple, powerful.
I've been playing with it for a few weeks and generally understand what is going on, but I do have a few usage questions that I couldn't find answered in the docs:
(1) Let's say I:
git clone something
git branch foo
git checkout foo
<make some changes>
git commit -a
git checkout master
git pull . foo
git push
git pull
Quoted 2 lines
what is actually happening? The pull appears to do something (i.e., I get:
git pull = git fetch + git merge. The notation you use above is obsoleted and no longer works in git 1.5.3. Instead you'd have to replace
git pull . foo
with
git merge foo
which will most likely clear up some confusion.
Quoted 6 lines
* refs/remotes/origin/master: fast forward to branch 'master' of
/home/krose/git-repository/baz/
old..new: 7cf088c..d344f98), but makes no changes locally since I have the latest revision. Another subsequent git pull does, in fact, say everything is up to date.
It should have made changes to your local tree, namely the ones you added to branch foo that weren't in master before you merged.
The fact that it turned out to be a fast forward only means that you had no additional commits on top of master, so the history in foo could be applied on top of master without any file-level merging taking place.
Quoted 5 lines
(2) Any way to disable this warning:
Warning: No merge candidate found because value of config option
"branch.local.merge" does not match any remote branch fetched.
Yes. Edit your .git/config file to add a merge candidate for your local branch.
Quoted 5 lines
(3) I notice I can't reset --hard a single file. So, if I want to revert a single file to some revision, blowing away my changes, what is the accepted way of doing this? Is there a way to do the equivalent of a p4 print foo@some_revision?
git checkout treeish path/to/file
according to the man-page at least. "treeish" here can be substituted for a revision, which in git is represented by a 40 byte SHA1 hash, but also has a lot of short-hand options. See "git help rev-list" for more info on that.
Quoted 8 lines
(4) I'm still not clear on when a dst should and should not be used in a refspec. It appears that one can only do non-fast forward updates to the branch that is checked out (which makes sense, since you may need to resolve), but other than that, what is the difference between
git checkout foo
git pull . master
Quoted 7 lines
and
git checkout master
git push . master:foo?
Here I'm clueless, except that this matches old syntax which is no longer valid. I'd recommend you to upgrade to 1.5.3 so that you get to use git-merge for local merges. The "use push/pull for merging" has caused enough confusion, I think.
Quoted 3 lines
(5) Are there any tools for managing some of the metadata (e.g., the origin URL) or is it expected that one edit it directly?
See the git-remote man page. It's available online if you don't have it.
Quoted 4 lines
Thanks for all your work on this: git fills a need I didn't know I had until I actually found myself using it: a completely decentralized patch management system.
It's more than that, but many of us share your feeling about it filling a need we didn't know we had.
Signature · 3 lines
Andreas Ericsson [email protected] OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231
Thanks for your help: your responses clear up a lot of things, and getting to 1.5.3 will be a priority, though I will probably wait until it appears in the Ubuntu pool, which unfortunately it has not yet. Differentiating merge and push as asymmetric operations (which pull and push do not imply, sounding symmetric) is a very good idea.
FWIW, I cannot believe I hadn't found Mr. Fields' doc before this: it seems pretty thorough, so I will read it before posting any further questions.
Thanks,
Kyle
Quoted 10 lines · Andreas Ericsson
git pull = git fetch + git merge. The notation you use above is obsoleted and no longer works in git 1.5.3. Instead you'd have to replace
git pull . foo
with
git merge foo
which will most likely clear up some confusion.
Huh? "git pull . foo" has always been the same as "git merge foo", I thought... Have we broken anything?
Quoted 8 lines
Quoted 5 lines
(2) Any way to disable this warning:
Warning: No merge candidate found because value of config option
"branch.local.merge" does not match any remote branch fetched.Yes. Edit your .git/config file to add a merge candidate for your local branch.
Or, say what branch you get from the remote you want to merge explicitly. You may not always merge the same branch from the remote. E.g.
$ git pull origin experimental $ git pull origin master
Quoted 10 lines
Quoted 10 lines
(4) I'm still not clear on when a dst should and should not be used in a refspec. It appears that one can only do non-fast forward updates to the branch that is checked out (which makes sense, since you may need to resolve), but other than that, what is the difference between
git checkout foo
git pull . masterand
Quoted 8 lines
Quoted 5 lines
git checkout master
git push . master:foo?
Here I'm clueless, except that this matches old syntax which is no longer valid.
Huh again about "no longer valid" part.
In any case, the former says "I am on foo branch, and I want to merge 'master' from _MY_ local repository". The latter says "I want to update the local branch 'foo' with what is in my 'master' branch, both local". They are totally different.
Please do _not_ spread backward incompatibility FUD.
Quoted 7 lines · Junio C Hamano
Quoted 5 lines · Andreas Ericsson
git pull = git fetch + git merge. The notation you use above is obsoleted and no longer works in git 1.5.3. Instead you'd have to replace
git pull . foo
Quoted 9 lines
Quoted 5 lines
with
git merge foo
which will most likely clear up some confusion.
Huh? "git pull . foo" has always been the same as "git merge foo", I thought... Have we broken anything?
Possibly. I noticed some weeks ago that "pull . branch" no longer worked and used merge instead. I shrugged it off as being of no moment, and can't recall if there were any real reasons for the merge to fail.
Quoted 4 lines
Quoted 3 lines
Quoted 1 line
Here I'm clueless, except that this matches old syntax which is no longer valid.
Quoted 8 lines
Huh again about "no longer valid" part.
In any case, the former says "I am on foo branch, and I want to merge 'master' from _MY_ local repository". The latter says "I want to update the local branch 'foo' with what is in my 'master' branch, both local". They are totally different.
Please do _not_ spread backward incompatibility FUD.
My apologies. I'll have to see if I can find what caused my own confusion in the first place.
Signature · 3 lines
Andreas Ericsson [email protected] OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231
Quoted 12 lines · Kyle Rose
After many years of dissatisfaction with the limitations of CVS, and after getting fed up with the complexity of configuring and maintaining a SVN setup, I just started using git for my own personal projects. I have to say it's quite nice and fits the UNIX philosophy well: fast, simple, powerful.
I've been playing with it for a few weeks and generally understand what is going on, but I do have a few usage questions that I couldn't find answered in the docs:
(1) Let's say I:
Quoted 7 lines
git clone something
git branch foo
git checkout foo
<make some changes>
git commit -a
git checkout master
git pull . foo
git merge foo
would be probably both clearer about the intent and more efficient here. After all, pull is just a simple wrapper for fetch + merge and you don't need the fetch from the repository to itself.
Quoted 2 lines
git push
git pull
Signature · 1 line
Jan 'Bulb' Hudec <[email protected]>
[jc: I think this is really worth saving somewhere. Could some kind soul make this into a patch to have under Documentation/ somewhere?]
Quoted 3 lines · Kyle Rose
(1) Let's say I:
git clone something
Origin repository's history is copied and you get their master in remotes/origin/master (aka remotes/origin/HEAD aka remotes/origin), and you can call that 'origin' for brevity. At the same time, you get your own 'master' branch that points at the same commit as the 'origin'. Your current branch pointed at by your HEAD is 'master'.
['origin' repository]
---A---B---C
^master==>
[your cloned repository]
---A---B---C
^master = HEAD
^remotes/origin
Quoted 1 line
git branch foo
You create a new branch of your own 'foo' in your repository, initially pointing at the same commit as your current commit (i.e. C as you are on 'master' after the clone).
==>
[your cloned repository]
---A---B---C
^master = HEAD
^remotes/origin
^foo
Quoted 1 line
git checkout foo
You switch from your current branch (i.e. 'master') to the named branch (i.e. 'foo'), making the latter the current branch. Your work tree will largely match the commit at the tip of the branch you are switching to, except that if you had any local changes (i.e. uncommitted) in your work tree, you take it along (but in this example you do not have any).
==>
[your cloned repository]
---A---B---C
^master
^remotes/origin
^foo = HEAD
Quoted 2 lines
<make some changes>
git commit -a
You build a commit whose parent is the commit your HEAD used to point at; the tip of your current branch advances.
==>
[your cloned repository]
---A---B---C---D
^foo = HEAD
^master
^remotes/origin
Quoted 1 line
git checkout master
You switch from your current branch (i.e. 'foo') to the named branch (i.e. 'master'), making the latter the current branch. Your work tree will largely match the commit at the tip of the branch you are switching to, except that if you had any local changes (i.e. uncommitted) in your work tree, you take it along (but in this example you do not have any).
==>
[your cloned repository]
---A---B---C---D
^foo
^master = HEAD
^remotes/origin
Quoted 1 line
git pull . foo
This "git pull" command instructs git to "from the repository '.', grab the commit the repository calls 'foo', and update my current branch by merging that commit". Because '.' is "the current directory", which in turn means "my repository", you do not have to really "grab the commit" --- you already have it locally.
"git merge foo" is more natural way to write this since 1.5.0 days. The latter command instructs git "update my current branch by merging commit I call 'foo'".
Now, looking at the above history graph, your current branch'es tip is at C (you are on 'master', remember?), and 'foo' is at D, which is an descendant of C. By definition, a merge between such commit pair is the descendant D, so your current branch is updated to D (this is called "fast forward").
==>
[your cloned repository]
---A---B---C---D
^foo
^master = HEAD
^remotes/origin
Quoted 1 line
git push
This is kind of "lazy" and "very not-git-like" command I literally *hate*. What "git push" does, whey you do not say anything about "where to" nor "what", is to "push all corresponding branches and tags to the repository you call 'origin'".
If you recall the very initial picture, the 'origin' repository has 'master' branch but not 'foo'. The only matching branch is 'master', and that is pointing at C over there, which is replaced by your 'master' which now points at 'D'.
['origin' repository]
---A---B---C
^master==>
['origin' repository]
---A---B---C---D
^masterNote that this update *MUST* be fast-forward by default. IOW, if somebody worked elsewhere and updated the 'master' branch at the 'origin' repository before your push, your 'push' will be prevented with an error message that tells you that remote 'master' is not a strict subset of what you are pushing.
Quoted 1 line
git pull
Instruct git to "grab the history from the 'origin' repository and update remotes/origin/* with its branch, and then update my current branch by merging its tip".
The first step of updating the remotes/origin again *MUST* be fast-forward by default.
==>
[your cloned repository]
---A---B---C---D
^foo
^master = HEAD
^remotes/origin
If you recall, you are on 'master' branch whose tip is at D. Now you are telling git to update it by merging what you fetched, which also is D. So nothing happens.
Quoted 4 lines
(2) Any way to disable this warning:
Warning: No merge candidate found because value of config option
"branch.local.merge" does not match any remote branch fetched.
Do as the warning says; I do not think the message can be any clearer (see Documentation/config.txt, or even better "The User's Manual"). Set branch.local.merge configuration variable if you want to always merge specific branch you obtain from the remote.
E.g.
[branch "local"]
remote = origin
merge = refs/heads/master
if you want "git pull", without saying what to pull from where, to fetch from 'origin' and merge its 'master' branch, when you are on your 'local' branch.
Quoted 4 lines
(3) I notice I can't reset --hard a single file. So, if I want to revert a single file to some revision, blowing away my changes, what is the accepted way of doing this? Is there a way to do the equivalent of a p4 print foo@some_revision?
I have no idea what p4 does, but:
git checkout -- path
updates the work tree file with the last version of paths you did "git add path",
git checkout HEAD -- path
updates the work tree file with the version of paths in the HEAD commit, and
git checkout some_version -- path
updates the work tree file with the version of paths in the named commit. For various ways to name commits, see git-rev-parse(1).
Quoted 5 lines
(4) I'm still not clear on when a dst should and should not be used in a refspec. It appears that one can only do non-fast forward updates to the branch that is checked out (which makes sense, since you may need to resolve), but other than that, what is the difference between
Quoted 7 lines
git checkout foo
git pull . masterand
git checkout master
git push . master:foo
The obvious difference is which branch you end up with.
Quoted 2 lines
(5) Are there any tools for managing some of the metadata (e.g., the origin URL) or is it expected that one edit it directly?
git-remote(1).