* git push to a non-bare repository
@ 2007-03-18 17:31 Matthieu Moy
2007-03-18 19:47 ` Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 27+ messages in thread
From: Matthieu Moy @ 2007-03-18 17:31 UTC (permalink / raw)
To: git
Hi,
I have a repository with a working tree on a machine A, did a clone to
another machine B and commited there locally.
I want my changes to get back into the first repository, so I did a
"push". The new commit is in the history, I can see it with "git log",
but the modifications are not in the working tree.
This time, it's OK: I didn't have any uncommited modifications on A,
so I just did a "git reset --hard HEAD" there.
But if I had some uncommited changes, "git reset --hard HEAD" means
data loss, which is precisely what I want to avoid by using a VCS. It
seems a solution is to do:
$ git reset --soft <commit-id-before-the-push>
$ git merge <commit-id-after-the-push>
But it means I have to remember <commit-id-before-the-push>.
I don't understand the design choice here: git had two options to
avoid this scenario:
1) update the working tree while doing the push. That's feasible with
good performance since git is present on the server, but leaves the
problem of possible conflicts.
2) let git remember what the local tree points to (not just the branch
name, but the commit id itself, stored in a place that "git push"
won't modify). Then, provide me a way to "update" to the latest
revision.
Fyi, bzr does this. Indeed, in bzr, a branch (let's say "repository"
in the git vocabulary) with a working tree just means a working tree
(AKA lightweight checkout) located in the same directory as a branch.
The working tree knows which revision it corresponds to, and where to
find its branch. There's a "bzr update" command to get my working tree
to the head of the branch, keeping the uncommited changes.
I believe this idea is very much linked to the "Lightweight Checkout"
idea (listed on the SoC ideas), since, in the case of multiple working
directories sharing the same .git, you don't want a commit in one tree
to affect the others.
So, did I miss something? Is there anything on the todo-list?
Thanks,
--
Matthieu
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: git push to a non-bare repository 2007-03-18 17:31 git push to a non-bare repository Matthieu Moy @ 2007-03-18 19:47 ` Junio C Hamano 2007-03-18 21:51 ` Sam Vilain 2007-03-19 2:00 ` Theodore Tso 2007-03-19 12:44 ` Sergio Callegari 2 siblings, 1 reply; 27+ messages in thread From: Junio C Hamano @ 2007-03-18 19:47 UTC (permalink / raw) To: Matthieu Moy; +Cc: git Matthieu Moy <Matthieu.Moy@imag.fr> writes: > I don't understand the design choice here: git had two options to > avoid this scenario: Actually, there are no such "design choices". That's entirely up to the repository owners to arrange post-update hook, to allow you to do anything you want. The default is not to encourage people (who do not know what they are doing anyway) to push into non-bare repository. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-18 19:47 ` Junio C Hamano @ 2007-03-18 21:51 ` Sam Vilain 2007-03-18 22:01 ` Jakub Narebski 2007-03-18 22:18 ` Junio C Hamano 0 siblings, 2 replies; 27+ messages in thread From: Sam Vilain @ 2007-03-18 21:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: Matthieu Moy, git Junio C Hamano wrote: >> I don't understand the design choice here: git had two options to >> avoid this scenario: >> > > Actually, there are no such "design choices". That's entirely > up to the repository owners to arrange post-update hook, to > allow you to do anything you want. > > The default is not to encourage people (who do not know what > they are doing anyway) to push into non-bare repository. > Maybe it's worth making it an error (that can be forced) if you're pushing to the head that's checked out in a non-bare repository ? It's pretty nasty behaviour for people used to darcs / bzr et al. Sam. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-18 21:51 ` Sam Vilain @ 2007-03-18 22:01 ` Jakub Narebski 2007-03-18 22:18 ` Junio C Hamano 1 sibling, 0 replies; 27+ messages in thread From: Jakub Narebski @ 2007-03-18 22:01 UTC (permalink / raw) To: git Sam Vilain wrote: > Junio C Hamano wrote: >>> I don't understand the design choice here: git had two options to >>> avoid this scenario: >> >> Actually, there are no such "design choices". That's entirely >> up to the repository owners to arrange post-update hook, to >> allow you to do anything you want. >> >> The default is not to encourage people (who do not know what >> they are doing anyway) to push into non-bare repository. >> > > Maybe it's worth making it an error (that can be forced) if you're > pushing to the head that's checked out in a non-bare repository ? > > It's pretty nasty behaviour for people used to darcs / bzr et al. Perhaps it would be for the best. BUT unless you arrange some fancy post-update hook you have two sane choices: * push to bare repository, with 1:1 refs mapping * push to non-bare repository, but with mapping pushed refs on pushee to remotes refs (remote / tracking branches) on remote side. In all other choices there madness lies... ;-) -- Jakub Narebski Warsaw, Poland ShadeHawk on #git ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-18 21:51 ` Sam Vilain 2007-03-18 22:01 ` Jakub Narebski @ 2007-03-18 22:18 ` Junio C Hamano 1 sibling, 0 replies; 27+ messages in thread From: Junio C Hamano @ 2007-03-18 22:18 UTC (permalink / raw) To: Sam Vilain; +Cc: Matthieu Moy, git Sam Vilain <sam@vilain.net> writes: > Junio C Hamano wrote: > ... > Maybe it's worth making it an error (that can be forced) if you're > pushing to the head that's checked out in a non-bare repository ? We talked about that in the past on the list. No. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-18 17:31 git push to a non-bare repository Matthieu Moy 2007-03-18 19:47 ` Junio C Hamano @ 2007-03-19 2:00 ` Theodore Tso 2007-03-19 1:55 ` Junio C Hamano 2007-03-19 9:19 ` Matthieu Moy 2007-03-19 12:44 ` Sergio Callegari 2 siblings, 2 replies; 27+ messages in thread From: Theodore Tso @ 2007-03-19 2:00 UTC (permalink / raw) To: git On Sun, Mar 18, 2007 at 06:31:21PM +0100, Matthieu Moy wrote: > I have a repository with a working tree on a machine A, did a clone to > another machine B and commited there locally. > > I want my changes to get back into the first repository, so I did a > "push". The new commit is in the history, I can see it with "git log", > but the modifications are not in the working tree. The general answer (which you've already received) is to tell folks is to simply don't use "git push" to remote trees; basically, if you ever have a non-bare repository, it doesn't do what you expect, and it will leave the novice user horribly confused. A much better answer is to simply go back to machine A, and pull from machine B. I was exploring though to see if there was anything we could do better, and so I used my standard test repository of the GNU Hello, world program, and did the following: git clone hello r1 git clone r1 r2 cd r1 <edit hello.c's headers to be GPL v2 only> git commit -a -m "GPL v2 only" cd ../r2 <edit hello.c so that the message printed is "Hello, world!" instead of "hello, world"> cd .. OK, so this sets up the standard test setup of repositories r1 and r2. r1 contains a committed change so that hello.c is GPLv2 only. r2 contains an uncommitted change to the actual text printed by hello.c. The changes are nicely seprated in distaince by over 100 lines, so there should be no problems with merges. Let's play... Experiment #1. Let's try pushing from r1 to r2. cd r1 git push ../r2 This pushes the change GPLv2 change from r1 to r2. However, it leaves the working tree and the index untouched, which leads to some very unexpected and surprising behavior: a) If you do a "git commit" you will commit the current contents of the index, which is usually the contents of the head of r2 before the push. b) If you do a "git commit -a" you will commit the modified changes to the working directory --- based off of the state of r2 before the push. What will therefore show up in the revision log is something which appears to be based off of the more recent change in r1, but which is really based off of the old history as of r2 before the push. All of this is bad, which is why "git push" to a non-bare repository is extremely surprising. (As an aside, what Bitkeeper would do is to update the working tree, but it added the constraint that it would only allow the "bk push" if the push resulted in a fast-forward merge, thus guaranteeing no conflicts, and if the none of the files that would need to be updated in the working tree had been locally modified; if either constraint were modified, the push would be aborted, and the remote repository not modified at all. It would be nice if we could enforce these constraints using the appropriate hooks, but from what I can tell the hooks aren't in the right place for us to be able to do that, or to be able to undo or recover from a bad push. More on that in a bit.) OK, so suppose we do the push anyway. As you suggested, one possible solution is: > $ git reset --soft <commit-id-before-the-push> > $ git merge <commit-id-after-the-push> > > But it means I have to remember <commit-id-before-the-push>. Is it at all possible to figure out <commit-id-before-the-push>? It seems the answer is no, and I suspect that's a bug. Maybe it doesn't make sense to save the original HEAD in ORIG_HEAD in r2, but surely the original HEAD should be saved in the reflog, right? Well, at the moment it saves it in neither case. The problem is without doing this, it is as far as I can tell impossible to determine what revision the index is currently corresponding to, and without this information, it's very limited in what you can do. What possible solution which you *can* do is: git diff > /tmp/stage-patch git reset --hard patch -p1 < /tmp/stage-patch But that seems a bit manual and somewhat kludgy. If we had the revision of r2 before the push, it would be possible to do a 3-way merge, which in some cases might result in a cleaner merge of the modified files in the working tree. Experiment #2. Let's try pulling from r2 to r1 So this is what we tell people they should do; so how well does it work in this case? <do the above experimental setup> cd r2 git pull ../r1 What do we get? Updating f2e3cc0..37508dc hello.c: needs update fatal: Entry 'hello.c' not uptodate. Cannot merge. hello.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) Oh, dear. Since hello.c was locally modified, git-merge refused to do a 3-way merge to the local file. That's unfortunate, since if it had, it would have succeeded, and in this case it would have done the right thing. git-checkout will do something similar, but it at has an -m option which will do a 3-way merge to update the local working file. Unfortunately git-merge and git-pull do not have such an option. 'twould be nice if it did, but that's going to have to wait someone wanting to scratch that particular itch... The failure leaves the index and the working tree in the same confused state as the "git push" scenario, though --- the index is still referring to original state of the tree before the pull, but the HEAD has been updated to after the pull, so "git commit" will lead to the same confusing behavior. Fortunately, though, when we do a pull, ORIG_HEAD and the reflog are updated, so we can get back to our original state via a command like this: git update-ref HEAD ORIG_HEAD So ok, let's break down the git pull into its two constiuent parts. The git-fetch and the git-merge. git fetch git merge FETCH_HEAD This fails in the same way: Updating f2e3cc0..37508dc hello.c: needs update fatal: Entry 'hello.c' not uptodate. Cannot merge. hello.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) And just as before, it leaves HEAD updated to FETCH_HEAD, even though it failed. So it's consistent, but that's not what the documentation for git-merge states: You may have local modifications in the working tree files. In other words, git-diff is allowed to report changes. However, the merge uses your working tree as the working area, and in order to prevent the merge operation from losing such changes, it makes sure that they do not interfere with the merge. Those complex tables in read-tree docu- mentation define what it means for a path to "interfere with the merge". And if your local modifications interfere with the merge, again, it stops before touching anything. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Well, it certainly stops before touching any local files, but it has already updated HEAD, which leaves things in a very confusion situation. Maybe it would be better if git-merge atomically failed and left HEAD back pointing at the original revision? - Ted ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:00 ` Theodore Tso @ 2007-03-19 1:55 ` Junio C Hamano 2007-03-19 2:21 ` Shawn O. Pearce 2007-03-19 9:19 ` Matthieu Moy 1 sibling, 1 reply; 27+ messages in thread From: Junio C Hamano @ 2007-03-19 1:55 UTC (permalink / raw) To: Theodore Tso; +Cc: git Theodore Tso <tytso@mit.edu> writes: > Is it at all possible to figure out <commit-id-before-the-push>? It > seems the answer is no, and I suspect that's a bug. Doesn't update hook get pre- and post- commit object name? ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 1:55 ` Junio C Hamano @ 2007-03-19 2:21 ` Shawn O. Pearce 2007-03-19 2:47 ` Theodore Tso 0 siblings, 1 reply; 27+ messages in thread From: Shawn O. Pearce @ 2007-03-19 2:21 UTC (permalink / raw) To: Junio C Hamano; +Cc: Theodore Tso, git Junio C Hamano <junkio@cox.net> wrote: > Theodore Tso <tytso@mit.edu> writes: > > > Is it at all possible to figure out <commit-id-before-the-push>? It > > seems the answer is no, and I suspect that's a bug. > > Doesn't update hook get pre- and post- commit object name? Yes, and the same is true in the new post-receive hook. -- Shawn. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:21 ` Shawn O. Pearce @ 2007-03-19 2:47 ` Theodore Tso 2007-03-19 2:56 ` Shawn O. Pearce 0 siblings, 1 reply; 27+ messages in thread From: Theodore Tso @ 2007-03-19 2:47 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git On Sun, Mar 18, 2007 at 10:21:43PM -0400, Shawn O. Pearce wrote: > Junio C Hamano <junkio@cox.net> wrote: > > Theodore Tso <tytso@mit.edu> writes: > > > > > Is it at all possible to figure out <commit-id-before-the-push>? It > > > seems the answer is no, and I suspect that's a bug. > > > > Doesn't update hook get pre- and post- commit object name? > > Yes, and the same is true in the new post-receive hook. In my comments, I was observing that *after* the push had succeeded, there was no way to find the commit-id-before-the-push, since neither the reflog nor ORIG_HEAD is getting updated. Is there a good reason why not? Would you accept a patch which caused the reflog and possibly ORIG_HEAD to be updated on the remote side of the push? When I was talking about a hook to enforce the BitKeeper semantics, the question is whether we have enough to enforce the following: * Only accept the push if it will result in a fast-forward merge (and if not, tell the user to do a git pull, merge locally, and then redo the git push) * Only accept the push if there are no locally modified files that would be affected when the working directory is updated to reflect the new HEAD I don't think there's any easy way to determine if these two criteria would be met besides trying to actually do the merge, and if it fails atomically back out to the original starting point, right? Or am I missing something painfully obvious? Since one of the applications where I might want to do something like this is a push a web site being maintained by git (where I don't want any the result of the interim attempted to merge to accidentally get seen by the web server), probably in order to do this right I'd have to have the hook script do a cp -rl of the repository+working tree to some scratch space, try to do the merge and update of the working tree, and if it succeeds, allow it to happen for real in the "live" tree, and if not, fail the merge. This seems awfully kludgy; is there some other way? - Ted ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:47 ` Theodore Tso @ 2007-03-19 2:56 ` Shawn O. Pearce 2007-03-19 3:21 ` Theodore Tso 2007-03-19 3:33 ` Theodore Tso 0 siblings, 2 replies; 27+ messages in thread From: Shawn O. Pearce @ 2007-03-19 2:56 UTC (permalink / raw) To: Theodore Tso; +Cc: Junio C Hamano, git Theodore Tso <tytso@mit.edu> wrote: > On Sun, Mar 18, 2007 at 10:21:43PM -0400, Shawn O. Pearce wrote: > > Junio C Hamano <junkio@cox.net> wrote: > > > Theodore Tso <tytso@mit.edu> writes: > > > > > > > Is it at all possible to figure out <commit-id-before-the-push>? It > > > > seems the answer is no, and I suspect that's a bug. > > > > > > Doesn't update hook get pre- and post- commit object name? > > > > Yes, and the same is true in the new post-receive hook. > > In my comments, I was observing that *after* the push had succeeded, > there was no way to find the commit-id-before-the-push, since neither > the reflog nor ORIG_HEAD is getting updated. Is there a good reason > why not? Would you accept a patch which caused the reflog and > possibly ORIG_HEAD to be updated on the remote side of the push? The reflog does update if the log file exists during a push (err, actually during receive-pack). Or if core.logAllRefUpdates is set to true. Now this isn't the default in a bare repository, but it should be the default in a repository with a working directory. So the case we are talking about should be seeing the reflog update. > When I was talking about a hook to enforce the BitKeeper semantics, > the question is whether we have enough to enforce the following: > > * Only accept the push if it will result in a fast-forward > merge (and if not, tell the user to do a git pull, merge > locally, and then redo the git push) Yes, the update hook can detect this. Actually receive-pack by default rejects *all* non-fast-forward pushes, even if the client side uses --force. > * Only accept the push if there are no locally modified files > that would be affected when the working directory is > updated to reflect the new HEAD The update hook could also perform this check; test if the ref being updated is the current branch, and if so, verify the index and working directory is clean. That's a simple run of git-symbolic-ref (to get the current branch) and git-runstatus (to check the index and working directory), is it not? If git-runstatus exits to indicate the tree is clean (nothing to commit) then a simple `read-tree -m -u HEAD $new` should update the working directory and index, right? -- Shawn. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:56 ` Shawn O. Pearce @ 2007-03-19 3:21 ` Theodore Tso 2007-03-19 3:53 ` Shawn O. Pearce 2007-03-19 3:33 ` Theodore Tso 1 sibling, 1 reply; 27+ messages in thread From: Theodore Tso @ 2007-03-19 3:21 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git On Sun, Mar 18, 2007 at 10:56:03PM -0400, Shawn O. Pearce wrote: > The reflog does update if the log file exists during a push (err, > actually during receive-pack). Or if core.logAllRefUpdates is set > to true. Now this isn't the default in a bare repository, but it > should be the default in a repository with a working directory. > So the case we are talking about should be seeing the reflog update. So I dug a little more deeply, and the problem is that the reflog for master was getting updated, but not the reflog for HEAD, and that's what "git reflog" was showing --- hence my confusion. What are the rules for when HEAD's reflog should get updated, and is this documented anywhere in the man pages? - Ted Script started on Sun 18 Mar 2007 11:11:59 PM EDT Top-level shell (parent script) Using ssh-agent pid 7679 <tytso@candygram> {/home/tytso/talks/dscm/git} 1% cp -r test1 test2 ; cd test2 <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 2% (cd r2; git-config core.logallrefupdates) true <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 3% cat r2/.git/refs/heads/master f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 4% cat r2/.git/logs/HEAD 0000000000000000000000000000000000000000 f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 Theodore Ts'o <tytso@mit.edu> 1174266825 -0400 <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 5% cat r2/.git/logs/refs/heads/master 0000000000000000000000000000000000000000 f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 Theodore Ts'o <tytso@mit.edu> 1174266825 -0400 <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 6% (cd r1 ; git push ../r2) updating 'refs/heads/master' from f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 to 37508dc11dbe274d021124057fd2d027f6ce9d17 Generating pack... Done counting 5 objects. Result has 3 objects. Deltifying 3 objects. 100% (3/3) done Writing 3 objects. 100% (3/3) done Total 3 (delta 2), reused 0 (delta 0) Unpacking 3 objects 100% (3/3) done refs/heads/master: f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 -> 37508dc11dbe274d021124057fd2d027f6ce9d17 <tytso@candygram> {/home/tytso/talks/dscm/git/test2} 7% cd r2 <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 8% cat .git/refs/heads/master 37508dc11dbe274d021124057fd2d027f6ce9d17 <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 9% cat .git/logs/HEAD 0000000000000000000000000000000000000000 f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 Theodore Ts'o <tytso@mit.edu> 1174266825 -0400 <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 10% cat .git/logs/refs/heads/master 0000000000000000000000000000000000000000 f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 Theodore Ts'o <tytso@mit.edu> 1174266825 -0400 f2e3cc0bb64c8c94b89ba07bfbdd1653584586f2 37508dc11dbe274d021124057fd2d027f6ce9d17 Theodore Ts'o <tytso@mit.edu> 1174274004 -0400 push <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 11% git reflog 37508dc... HEAD@{0}: <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 13% git version git version 1.5.0.5.425.g9cec6-dirty <tytso@candygram> {/home/tytso/talks/dscm/git/test2/r2} [master] 14% exit Script done on Sun 18 Mar 2007 11:14:28 PM EDT ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 3:21 ` Theodore Tso @ 2007-03-19 3:53 ` Shawn O. Pearce 2007-03-19 4:08 ` Nicolas Pitre 2007-03-19 23:58 ` Sam Vilain 0 siblings, 2 replies; 27+ messages in thread From: Shawn O. Pearce @ 2007-03-19 3:53 UTC (permalink / raw) To: Theodore Tso; +Cc: Junio C Hamano, git Theodore Tso <tytso@mit.edu> wrote: > So I dug a little more deeply, and the problem is that the reflog for > master was getting updated, but not the reflog for HEAD, and that's > what "git reflog" was showing --- hence my confusion. > > What are the rules for when HEAD's reflog should get updated, and is > this documented anywhere in the man pages? It is buried down in write_ref_sha1 (in refs.c). The rule is if the name of the ref given to us for update does not match the actual ref we are about to change, we log to both the original ref name given and the actual ref name. This handles the case of HEAD being a symref to some actual branch; we update the HEAD reflog and the actual branch reflog whenever someone updates HEAD. Which is what we are usually doing from tools like git-checkout. receive-pack isn't updating the HEAD reflog as its updating the actual branch, not HEAD. If you pushed instead to HEAD you should see the HEAD reflog entry too. Its a little ugly here as I'm not sure we should always update HEAD's reflog if HEAD points at a branch we are actually updating. Maybe we should though in receive-pack ? -- Shawn. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 3:53 ` Shawn O. Pearce @ 2007-03-19 4:08 ` Nicolas Pitre 2007-03-19 6:25 ` Theodore Tso 2007-03-19 23:58 ` Sam Vilain 1 sibling, 1 reply; 27+ messages in thread From: Nicolas Pitre @ 2007-03-19 4:08 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Theodore Tso, Junio C Hamano, git On Sun, 18 Mar 2007, Shawn O. Pearce wrote: > Theodore Tso <tytso@mit.edu> wrote: > > So I dug a little more deeply, and the problem is that the reflog for > > master was getting updated, but not the reflog for HEAD, and that's > > what "git reflog" was showing --- hence my confusion. > > > > What are the rules for when HEAD's reflog should get updated, and is > > this documented anywhere in the man pages? > > It is buried down in write_ref_sha1 (in refs.c). The rule is if the > name of the ref given to us for update does not match the actual > ref we are about to change, we log to both the original ref name > given and the actual ref name. > > This handles the case of HEAD being a symref to some actual branch; > we update the HEAD reflog and the actual branch reflog whenever > someone updates HEAD. Which is what we are usually doing from > tools like git-checkout. > > receive-pack isn't updating the HEAD reflog as its updating the > actual branch, not HEAD. If you pushed instead to HEAD you should > see the HEAD reflog entry too. This is indeed a corner case. And it was never considered before as great care was made at the time to be sure pushes wouldn't create any reflogs on the remote side, which is effectively done by not automatically enabling reflogs on bare repos. > Its a little ugly here as I'm not sure we should always update > HEAD's reflog if HEAD points at a branch we are actually updating. > Maybe we should though in receive-pack ? If the meaning of HEAD changed (although indirectly) because HEAD happens to point to the branch that just got updated then logically the HEAD reflog should be updated too. On the other hand the HEAD reflog should reflect operations performed on HEAD. Since the push updates the branch directly it is not exactly performing some operation on HEAD since HEAD could point anywhere and that wouldn't change the push at all. Meaning that for the discussion of pushing to a non-bare repository with a dirty working tree... If the branch being pushed into is not pointed to by HEAD then no consideration what so ever about the working tree should be made, and no update to the HEAD reflog made of course. Nicolas ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 4:08 ` Nicolas Pitre @ 2007-03-19 6:25 ` Theodore Tso 2007-03-19 6:44 ` Junio C Hamano 2007-03-19 15:16 ` Nicolas Pitre 0 siblings, 2 replies; 27+ messages in thread From: Theodore Tso @ 2007-03-19 6:25 UTC (permalink / raw) To: Nicolas Pitre; +Cc: Shawn O. Pearce, Junio C Hamano, git On Mon, Mar 19, 2007 at 12:08:47AM -0400, Nicolas Pitre wrote: > > Its a little ugly here as I'm not sure we should always update > > HEAD's reflog if HEAD points at a branch we are actually updating. > > Maybe we should though in receive-pack ? > > If the meaning of HEAD changed (although indirectly) because HEAD > happens to point to the branch that just got updated then logically the > HEAD reflog should be updated too. On the other hand the HEAD reflog > should reflect operations performed on HEAD. Since the push updates the > branch directly it is not exactly performing some operation on HEAD > since HEAD could point anywhere and that wouldn't change the push at > all. > > Meaning that for the discussion of pushing to a non-bare repository with > a dirty working tree... If the branch being pushed into is not pointed > to by HEAD then no consideration what so ever about the working tree > should be made, and no update to the HEAD reflog made of course. Right, but if the branch being pointed to is pointed to by HEAD I would argue that the reflog for HEAD should be updated, since operations that reference HEAD will see a new commit, and and it will be confusing when "git reflog" shows no hint of the change. Of couse, if the branch being pushed to isn't one which is pointed by HEAD, of course HEAD's reflog shouldn't be updated. - Ted ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 6:25 ` Theodore Tso @ 2007-03-19 6:44 ` Junio C Hamano 2007-03-19 15:20 ` Nicolas Pitre 2007-03-19 15:16 ` Nicolas Pitre 1 sibling, 1 reply; 27+ messages in thread From: Junio C Hamano @ 2007-03-19 6:44 UTC (permalink / raw) To: Theodore Tso; +Cc: Nicolas Pitre, Shawn O. Pearce, git Theodore Tso <tytso@mit.edu> writes: > Right, but if the branch being pointed to is pointed to by HEAD I > would argue that the reflog for HEAD should be updated, since > operations that reference HEAD will see a new commit, and and it will > be confusing when "git reflog" shows no hint of the change. > > Of couse, if the branch being pushed to isn't one which is pointed by > HEAD, of course HEAD's reflog shouldn't be updated. If we were to do this properly, we probably would need to restructure the reflog update code for the HEAD in a major way. "git-update-ref refs/heads/foo $newvalue" when HEAD points at branch 'foo' currently does not update HEAD reflog because the current definition of HEAD reflog is (as Nico mentioned) log of changes made through HEAD symref. Instead, we would need a reverse lookup every time any ref is updated to see if that ref is pointed by any symbolics ref and update the reflogs of those symbolic refs. This is expensive to do in general, though, because there is no backpointer to list of symbolic refs that point at a non-symbolic ref. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 6:44 ` Junio C Hamano @ 2007-03-19 15:20 ` Nicolas Pitre 0 siblings, 0 replies; 27+ messages in thread From: Nicolas Pitre @ 2007-03-19 15:20 UTC (permalink / raw) To: Junio C Hamano; +Cc: Theodore Tso, Shawn O. Pearce, git On Sun, 18 Mar 2007, Junio C Hamano wrote: > Theodore Tso <tytso@mit.edu> writes: > > > Right, but if the branch being pointed to is pointed to by HEAD I > > would argue that the reflog for HEAD should be updated, since > > operations that reference HEAD will see a new commit, and and it will > > be confusing when "git reflog" shows no hint of the change. > > > > Of couse, if the branch being pushed to isn't one which is pointed by > > HEAD, of course HEAD's reflog shouldn't be updated. > > If we were to do this properly, we probably would need to > restructure the reflog update code for the HEAD in a major way. > "git-update-ref refs/heads/foo $newvalue" when HEAD points at > branch 'foo' currently does not update HEAD reflog because the > current definition of HEAD reflog is (as Nico mentioned) log of > changes made through HEAD symref. Instead, we would need a > reverse lookup every time any ref is updated to see if that ref > is pointed by any symbolics ref and update the reflogs of those > symbolic refs. This is expensive to do in general, though, > because there is no backpointer to list of symbolic refs that > point at a non-symbolic ref. But practically speaking... is there that many cases where a branch is updated directly instead of the operation performed through HEAD? We identified one case which is a push to a non bare repo. If those cases are very few (and they _should_ be very few) then we might simply cheat a little and update HEAD separately in those cases. Nicolas ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 6:25 ` Theodore Tso 2007-03-19 6:44 ` Junio C Hamano @ 2007-03-19 15:16 ` Nicolas Pitre 1 sibling, 0 replies; 27+ messages in thread From: Nicolas Pitre @ 2007-03-19 15:16 UTC (permalink / raw) To: Theodore Tso; +Cc: Shawn O. Pearce, Junio C Hamano, git On Mon, 19 Mar 2007, Theodore Tso wrote: > On Mon, Mar 19, 2007 at 12:08:47AM -0400, Nicolas Pitre wrote: > > If the meaning of HEAD changed (although indirectly) because HEAD > > happens to point to the branch that just got updated then logically the > > HEAD reflog should be updated too. On the other hand the HEAD reflog > > should reflect operations performed on HEAD. Since the push updates the > > branch directly it is not exactly performing some operation on HEAD > > since HEAD could point anywhere and that wouldn't change the push at > > all. > > > > Meaning that for the discussion of pushing to a non-bare repository with > > a dirty working tree... If the branch being pushed into is not pointed > > to by HEAD then no consideration what so ever about the working tree > > should be made, and no update to the HEAD reflog made of course. > > Right, but if the branch being pointed to is pointed to by HEAD I > would argue that the reflog for HEAD should be updated, since > operations that reference HEAD will see a new commit, and and it will > be confusing when "git reflog" shows no hint of the change. > > Of couse, if the branch being pushed to isn't one which is pointed by > HEAD, of course HEAD's reflog shouldn't be updated. I think we're saying the exact same thing. Nicolas ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 3:53 ` Shawn O. Pearce 2007-03-19 4:08 ` Nicolas Pitre @ 2007-03-19 23:58 ` Sam Vilain 2007-03-20 0:49 ` Junio C Hamano 1 sibling, 1 reply; 27+ messages in thread From: Sam Vilain @ 2007-03-19 23:58 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Theodore Tso, Junio C Hamano, git Shawn O. Pearce wrote: > receive-pack isn't updating the HEAD reflog as its updating the > actual branch, not HEAD. If you pushed instead to HEAD you should > see the HEAD reflog entry too. > What about splitting HEAD when you push to the underlying branch, and making HEAD a non-symref? Sam. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 23:58 ` Sam Vilain @ 2007-03-20 0:49 ` Junio C Hamano 2007-03-20 0:54 ` Junio C Hamano 0 siblings, 1 reply; 27+ messages in thread From: Junio C Hamano @ 2007-03-20 0:49 UTC (permalink / raw) To: Sam Vilain; +Cc: Shawn O. Pearce, Theodore Tso, git Sam Vilain <sam@vilain.net> writes: > Shawn O. Pearce wrote: >> receive-pack isn't updating the HEAD reflog as its updating the >> actual branch, not HEAD. If you pushed instead to HEAD you should >> see the HEAD reflog entry too. > > What about splitting HEAD when you push to the underlying branch, and > making HEAD a non-symref? I do not think any of the complication is needed, and I think somebody mentioned a good example, which is a firewalled host that can only be pushed into. In that example, even though he knows he could fetch in reverse direction in the ideal world, the network configuration does not let him do so, hence need for a push. To deal with that sanely, people who push between non bare repositories can just forget about pushing into branch heads. Instead, they can arrange their pushes to be a true mirror image of their fetch that they wish could do. To illustrate: On repo A that can only be pushed into, if you _could_ fetch from repo B, you would: $ git fetch B with something like this: [remote "B"] fetch = refs/heads/*:refs/remotes/B/* But unfortunately because you can only push into A from B, you would run this on B instead: $ git push A with: [remote "A"] push = refs/heads/*:refs/remotes/B/* And after you perform your push, you come to the machine with repo A on it, and remembering that what you did was a mirror image of "git fetch B", you would: $ git merge remotes/B/master and you are done. In other words, don't think of refs/remotes/B as something that is for the use of "git fetch". Its purpose is to track the remote repository B's heads. You maintain that hierarchy by issuing fetch in repository A. You can issue push in repository B to do so as well. I push into a live repository almost every day. My typical day concludes like this: gitster$ git push kernel-org-private gitster$ ssh kernel.org kernel.org$ git merge origin kernel.org$ Meta/Doit -pedantic & kernel.org$ exit ... go drink my tea ... where (1) gitster is my private development machine (2) kernel.org is a machine made available to me by friendly k.org folks (3) Meta is a checkout of my 'todo' branch and (4) Doit is a script to build all four public branches. I always leave 'master' checked out on my kernel.org repository, and the push from my private machine is done with (I still use the non separate-remote layout): Push: refs/heads/master:refs/heads/origin Push: refs/heads/next:refs/heads/next Push: +refs/heads/pu:refs/heads/pu Push: refs/heads/maint:refs/heads/maint So the first thing I do after logging in to kernel.org machine is to run "git merge origin" to bring the 'master' up-to-date. If you think of 'push' being mirror image of 'fetch' you would understand why. It is like issuing "git fetch" on kernel.org machine to retrive the hot-off-the-press from my private machine and then "git merge" it (usually "git pull" would do that as a single step). However, sometimes I accidentally leave 'next' checked out. If I find out that I left non 'master' checked out, I would do "git reset --hard HEAD" before doing anything else, and I do not want my push to sometimes result in detached HEAD and sometimes not. I do not want to lose the information which branch I was on last (because the next thing I would do is on which branch Meta/Doit failed). If I _were_ annoyed enough by sometimes mistakenly pushing into the live branch, I would switch to separate remote layout and push into remotes/origin/* hierarchy, and there will be truly nothing to worry about after that point. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-20 0:49 ` Junio C Hamano @ 2007-03-20 0:54 ` Junio C Hamano 0 siblings, 0 replies; 27+ messages in thread From: Junio C Hamano @ 2007-03-20 0:54 UTC (permalink / raw) To: Sam Vilain; +Cc: Shawn O. Pearce, Theodore Tso, git Junio C Hamano <junkio@cox.net> writes: > However, sometimes I accidentally leave 'next' checked out. If > I find out that I left non 'master' checked out, I would do "git > reset --hard HEAD" before doing anything else, and I do not want > my push to sometimes result in detached HEAD and sometimes not. > I do not want to lose the information which branch I was on last > (because the next thing I would do is on which branch Meta/Doit s/do is on/do is to find out on/; > failed). If I _were_ annoyed enough by sometimes mistakenly > pushing into the live branch, I would switch to separate remote > layout and push into remotes/origin/* hierarchy, and there will > be truly nothing to worry about after that point. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:56 ` Shawn O. Pearce 2007-03-19 3:21 ` Theodore Tso @ 2007-03-19 3:33 ` Theodore Tso 2007-03-19 3:47 ` Shawn O. Pearce 1 sibling, 1 reply; 27+ messages in thread From: Theodore Tso @ 2007-03-19 3:33 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git On Sun, Mar 18, 2007 at 10:56:03PM -0400, Shawn O. Pearce wrote: > > When I was talking about a hook to enforce the BitKeeper semantics, > > the question is whether we have enough to enforce the following: > > > > * Only accept the push if it will result in a fast-forward > > merge (and if not, tell the user to do a git pull, merge > > locally, and then redo the git push) > > Yes, the update hook can detect this. Actually receive-pack by > default rejects *all* non-fast-forward pushes, even if the client > side uses --force. Ah, so that's controlled by receive.denyNonFastForwards, right? Cool, I missed that. Thanks!! Documentation/config.txt doesn't say it defaults to true, but from your comments that is the default? > > * Only accept the push if there are no locally modified files > > that would be affected when the working directory is > > updated to reflect the new HEAD > > The update hook could also perform this check; test if the ref > being updated is the current branch, and if so, verify the index and > working directory is clean. That's a simple run of git-symbolic-ref > (to get the current branch) and git-runstatus (to check the index > and working directory), is it not? > > If git-runstatus exits to indicate the tree is clean (nothing to > commit) then a simple `read-tree -m -u HEAD $new` should update > the working directory and index, right? What git-runstatus will allow me to do is to abort if there are any local modifications, regardless of whether or not they would conflict with the working tree update. The key phrase in my criteria was no locally modified files "THAT WOULD BE AFFECTED". What I could do with BitKeeper is that I could modify some file like schedule.html on my webserver, and then push a changeset from my laptop to would update sermons.html, and it would allow the push --- since it would change the file sermons.html, and not touch schedule.html. But if I modified schedule.html on my laptop and then committed it, and *then* try to push that changeset to the webserver, it would abort since in order to accept the changeset, it would have to update the working tree, and that would clash with the locally modified schedule.html file. At thta point I'd have to login to the webserver, revert the local modification and bring it back down my laptop and include it in a proper changeset. Yeah, I probably shouldn't have ever modified the file locally on the webserver, but that would sometimes happen when I was in a rush, and it was nice when it Just Worked. - Ted ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 3:33 ` Theodore Tso @ 2007-03-19 3:47 ` Shawn O. Pearce 2007-03-19 4:14 ` Junio C Hamano 0 siblings, 1 reply; 27+ messages in thread From: Shawn O. Pearce @ 2007-03-19 3:47 UTC (permalink / raw) To: Theodore Tso; +Cc: Junio C Hamano, git Theodore Tso <tytso@mit.edu> wrote: > Ah, so that's controlled by receive.denyNonFastForwards, right? Cool, > I missed that. Thanks!! > > Documentation/config.txt doesn't say it defaults to true, but from > your comments that is the default? Ah, my bad, it defaults to false: static int deny_non_fast_forwards = 0; I should have known better, as I run a 1.5.x (aka 'next') server for a workgroup and I never have that set, but use instead a complex update hook that decides if a fast-forward is required or not. > > > * Only accept the push if there are no locally modified files > > > that would be affected when the working directory is > > > updated to reflect the new HEAD > > > > If git-runstatus exits to indicate the tree is clean (nothing to > > commit) then a simple `read-tree -m -u HEAD $new` should update > > the working directory and index, right? > > What git-runstatus will allow me to do is to abort if there are any > local modifications, regardless of whether or not they would conflict > with the working tree update. The key phrase in my criteria was no > locally modified files "THAT WOULD BE AFFECTED". git-diff $old $new | git-apply --index ? If the patch does not apply, nothing gets updated. If it does apply, the index is also updated and stat data updated. OK, it doesn't quite handle every case, as sometimes a patch will reject but the internal 3-way merge from xdiff that is called by merge-recursive will succeed, but this does protect your working tree and doesn't require making a temporary copy. Of course another possible approach is to stuff the entire working directory into a temporary tree, and then merge. If the merge doesn't work, you can reset to the temporary tree. Unfortunately the working directory is "in flux" during that process... its not atomic. -- Shawn. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 3:47 ` Shawn O. Pearce @ 2007-03-19 4:14 ` Junio C Hamano 0 siblings, 0 replies; 27+ messages in thread From: Junio C Hamano @ 2007-03-19 4:14 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Theodore Tso, git "Shawn O. Pearce" <spearce@spearce.org> writes: > git-diff $old $new | git-apply --index ? > > If the patch does not apply, nothing gets updated. If it does apply, > the index is also updated and stat data updated. And if you are only checking then perhaps instead of --index use --check, so that the actual updates are deferred? ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 2:00 ` Theodore Tso 2007-03-19 1:55 ` Junio C Hamano @ 2007-03-19 9:19 ` Matthieu Moy 2007-03-19 10:01 ` Jakub Narebski 2007-03-21 17:20 ` Neil Schemenauer 1 sibling, 2 replies; 27+ messages in thread From: Matthieu Moy @ 2007-03-19 9:19 UTC (permalink / raw) To: git Theodore Tso <tytso@mit.edu> writes: > On Sun, Mar 18, 2007 at 06:31:21PM +0100, Matthieu Moy wrote: >> I have a repository with a working tree on a machine A, did a clone to >> another machine B and commited there locally. >> >> I want my changes to get back into the first repository, so I did a >> "push". The new commit is in the history, I can see it with "git log", >> but the modifications are not in the working tree. > > The general answer (which you've already received) is to tell folks is > to simply don't use "git push" to remote trees; basically, if you ever > have a non-bare repository, it doesn't do what you expect, and it will > leave the novice user horribly confused. A much better answer is to > simply go back to machine A, and pull from machine B. It's not really an option in my case. A is a fixe-IP/fixe-DNS machine, while B is my home machine, behind a NAT modem-router. So, I'd have to figure out my home IP, port-forward the ssh port from the modem to my machine, ... If I understand correctly the other answers, I have two options: * Git doesn't manage this case, and doesn't care about me loosing data if they're not commited, I'll have to do it myself with hooks. * Create a bare repository on machine A, and clone it to a non-bare repo on which I'll work. But that means duplicating the repository on the same filesystem of the same machine. Not really satisfactory either. The "light checkout" feature would make it better, but I'm still worried about what will happen to my light checkout when someone pushes to the repository. -- Matthieu ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 9:19 ` Matthieu Moy @ 2007-03-19 10:01 ` Jakub Narebski 2007-03-21 17:20 ` Neil Schemenauer 1 sibling, 0 replies; 27+ messages in thread From: Jakub Narebski @ 2007-03-19 10:01 UTC (permalink / raw) To: git Matthieu Moy wrote: > * Create a bare repository on machine A, and clone it to a non-bare > repo on which I'll work. But that means duplicating the repository > on the same filesystem of the same machine. Not really satisfactory > either. The "light checkout" feature would make it better, but I'm > still worried about what will happen to my light checkout when > someone pushes to the repository. You can share repository object database using alternates. -- Jakub Narebski Warsaw, Poland ShadeHawk on #git ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-19 9:19 ` Matthieu Moy 2007-03-19 10:01 ` Jakub Narebski @ 2007-03-21 17:20 ` Neil Schemenauer 1 sibling, 0 replies; 27+ messages in thread From: Neil Schemenauer @ 2007-03-21 17:20 UTC (permalink / raw) To: git Matthieu Moy <Matthieu.Moy@imag.fr> wrote: > It's not really an option in my case. A is a fixe-IP/fixe-DNS machine, > while B is my home machine, behind a NAT modem-router. So, I'd have to > figure out my home IP, port-forward the ssh port from the modem to my > machine, ... I think this is a pretty common scenario. I have a central server that I would like to push to and a bunch of other machines behind firewalls. Pulling from the central machine is not practical. Neil ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: git push to a non-bare repository 2007-03-18 17:31 git push to a non-bare repository Matthieu Moy 2007-03-18 19:47 ` Junio C Hamano 2007-03-19 2:00 ` Theodore Tso @ 2007-03-19 12:44 ` Sergio Callegari 2 siblings, 0 replies; 27+ messages in thread From: Sergio Callegari @ 2007-03-19 12:44 UTC (permalink / raw) To: git Hi, Matthieu Moy <Matthieu.Moy <at> imag.fr> writes: > > Hi, > > I have a repository with a working tree on a machine A, did a clone to > another machine B and commited there locally. > > I want my changes to get back into the first repository, so I did a > "push". The new commit is in the history, I can see it with "git log", > but the modifications are not in the working tree. > > This time, it's OK: I didn't have any uncommited modifications on A, > so I just did a "git reset --hard HEAD" there. At times I have a similar scenario, working with both an office-pc (attached to the internet with a public static address) and a laptop (either detached from the internet or attached to it under a dynamic address and NAT) > But if I had some uncommited changes, "git reset --hard HEAD" means > data loss, which is precisely what I want to avoid by using a VCS. It > seems a solution is to do: > > $ git reset --soft <commit-id-before-the-push> > $ git merge <commit-id-after-the-push> I think that there might also be another option... perhaps in some cases you might want to commit the local changes by branching at <commit-id-before-the-push>... For instance: * you work on the office-pc: work work work (you do not commit yet, as you expect you will be able to finish your stuff and commit after that) * but for some reason you do not finish, you go away and you start working on the laptop... * you cannot pull the changes from the office-pc (as they are not committed) and assume you cannot or don't want to retrieve them otherwise... so you start working on what you have... work work work ... commit. You do not branch before committing as this is a finished thing and you now believe it deserves going on your current branch... (or you just have forgotten about the hanging stuff on the office-pc)... * As soon as you can, you push to the office-pc * Since the local changes on the office-pc are relative to something that has suddendly got older than the current branch-tip, you might want to merge, but you also might not want to... you might prefer to complete the thing and first test it as is... in this case you might want to branch, rather than merging. So when you push to a non-bare repo, it might probably be nice to be able to select between different behaviors: A) Try to auto merge and refuse the push if merging is impossible (as it is currently suggested) B) Accept the push anyway (in the end if one machine is under NAT, pushing is the only way to propagate changes), update the branch, loose the head and store somewhere some information like "I used to be in branch so and so, but I am not anymore at the branch tip since that has been changed, local changes are against commit ..." In this way the non-bare repo can start working as if it has become a headless checkout with local changes, explaining the situation and suggesting appropriate action (either merging or branching) to the user... something like: git status (or git commit) No current branch since the repository has been changed from outside this working tree... Cannot commit... Your last branch was ... Possible options < suggestion for merging > < suggestion for branching > I do not know if this makes any sense at all, since my usage of git is somehow limited and atypical (e.g. due to the 2 machines) and I might be missing many many implications... However B looks like a behavior that could be applied also in the case of multiple working trees insisting on a single repo, like in Junio's recen post where he wrote: > These days I use a few working trees that are connected to my > primary repository (which also has a working tree). The primary > repository is in /src/git, and other ones look like this: > > : gitster git.wk0; ls -l .git/ > total 120 > drwxrwsr-x 3 junio src 4096 Mar 5 16:22 ./ > drwxrwsr-x 15 junio src 16384 Mar 5 16:23 ../ > -rw-rw-r-- 1 junio src 41 Mar 5 16:22 HEAD > lrwxrwxrwx 1 junio src 27 Mar 3 22:53 config -> /src/git/.git/config > lrwxrwxrwx 1 junio src 26 Mar 3 22:53 hooks -> /src/git/.git/hooks/ > -rw-rw-r-- 1 junio src 82455 Mar 5 16:22 index > lrwxrwxrwx 1 junio src 25 Mar 3 22:53 info -> /src/git/.git/info/ > drwxrwsr-x 3 junio src 4096 Mar 3 22:59 logs/ > lrwxrwxrwx 1 junio src 28 Mar 3 22:53 objects -> /src/git/.git/objects/ > lrwxrwxrwx 1 junio src 32 Mar 3 22:53 packed-refs -> /src/git/.git/packed-refs > lrwxrwxrwx 1 junio src 25 Mar 3 22:53 refs -> /src/git/.git/refs/ > lrwxrwxrwx 1 junio src 28 Mar 3 22:53 remotes -> /src/git/.git/remotes/ > lrwxrwxrwx 1 junio src 29 Mar 3 22:53 rr-cache -> /src/git/.git/rr-cache/ > > It shares everything other than HEAD and the index (the reflog > for branches are also shared by a symlink .git/logs/refs > pointing at the one in the primary repository). > > This risks confusion for an uninitiated if you update a ref that > is checked out in another working tree, but modulo that caveat > it works reasonably well. > > We might want to add an option to 'git-clone' to create > something like this, but I am somewhat worried about the newbie > confusion factor. Perhaps... > > $ git clone --i-know-what-i-am-doing-give-me-an-alternate-working-tree \ > /src/git /src/git.wk0 So, did I miss something? Many thanks, Sergio ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2007-03-21 17:40 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-03-18 17:31 git push to a non-bare repository Matthieu Moy 2007-03-18 19:47 ` Junio C Hamano 2007-03-18 21:51 ` Sam Vilain 2007-03-18 22:01 ` Jakub Narebski 2007-03-18 22:18 ` Junio C Hamano 2007-03-19 2:00 ` Theodore Tso 2007-03-19 1:55 ` Junio C Hamano 2007-03-19 2:21 ` Shawn O. Pearce 2007-03-19 2:47 ` Theodore Tso 2007-03-19 2:56 ` Shawn O. Pearce 2007-03-19 3:21 ` Theodore Tso 2007-03-19 3:53 ` Shawn O. Pearce 2007-03-19 4:08 ` Nicolas Pitre 2007-03-19 6:25 ` Theodore Tso 2007-03-19 6:44 ` Junio C Hamano 2007-03-19 15:20 ` Nicolas Pitre 2007-03-19 15:16 ` Nicolas Pitre 2007-03-19 23:58 ` Sam Vilain 2007-03-20 0:49 ` Junio C Hamano 2007-03-20 0:54 ` Junio C Hamano 2007-03-19 3:33 ` Theodore Tso 2007-03-19 3:47 ` Shawn O. Pearce 2007-03-19 4:14 ` Junio C Hamano 2007-03-19 9:19 ` Matthieu Moy 2007-03-19 10:01 ` Jakub Narebski 2007-03-21 17:20 ` Neil Schemenauer 2007-03-19 12:44 ` Sergio Callegari
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).