* Pushing to a non-bare repository
@ 2007-02-03 3:01 Steven Grimm
2007-02-03 3:26 ` Junio C Hamano
0 siblings, 1 reply; 6+ messages in thread
From: Steven Grimm @ 2007-02-03 3:01 UTC (permalink / raw)
To: git
This keeps coming up as I introduce people to git. In previous
discussions, the conclusion often seems to be that users don't really
know what they want the semantics to be. So here's what I want. I think
it's actually not that complicated to get something that'll be far more
useful than what we have today.
1. If the target repo has a branch other than the target branch checked
out, allow the push and don't touch the working copy. (By "allow the
push" here I mean proceed with the existing push behavior, which might
still error out if, e.g., the target branch has commits that aren't in
the local repo yet.)
2. If the target repo has the target branch checked out and the working
copy equals its head, allow the push and reset the working copy to the
newly created head. Basically this is equivalent to a simple
fast-forward pull in the other direction.
3. If the target repo has the target branch checked out and there are
uncommitted edits, block the push and return an error indicating the
target repo is being edited and can't be pushed to until the edits are
undone or committed.
That's it. No merging of local edits in the target, just the same
semantics as a push to a bare repo (in case 1) or a fast-forward
operation with no merging (case 2). Would it be even nicer to have some
automatic merge magic in case 3? Maybe, but cases 1 and 2 are still very
useful without it.
In particular, those two cases would completely cover the two situations
where I most often want to push to a checked-out parent: a common
integration area that we can browse manually or point a Web server or a
compiler at as a source directory, and (more important to me) a
bidirectional sync mechanism between my laptop and my server, where I
want to commit my changes then send them to the other side to continue
working. Right now git requires me to set up a dummy parent repository
that both my laptop and my server repositories are clones of, and I have
to run an extra "pull" after each push to get the changes where I want
them. No purpose is served by that parent repository except to satisfy
git's requirement that a push target has to be bare.
Another place where the current situation is a bit weak is when I want
to clone someone's repo to help them fix a bug. If I clone it onto my
laptop, I end up having to email diffs back; our corporate network
doesn't allow us to make TCP connections to our laptops, only from our
laptops, so it is impossible for the other person to log onto the server
and pull from my clone. If I could push back to a topic branch in the
other person's repo, they could merge my change into their working copy
at their leisure.
Is this actually more complicated than the above? What am I missing?
-Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pushing to a non-bare repository
2007-02-03 3:01 Pushing to a non-bare repository Steven Grimm
@ 2007-02-03 3:26 ` Junio C Hamano
2007-02-03 9:46 ` Simon 'corecode' Schubert
0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2007-02-03 3:26 UTC (permalink / raw)
To: Steven Grimm; +Cc: git
Steven Grimm <koreth@midwinter.com> writes:
> This keeps coming up as I introduce people to git. In previous
> discussions, the conclusion often seems to be that users don't really
> know what they want the semantics to be.
I do not think that was the conclusion. My suggestion to you
would be to stop thinking as if push is a converse of pull
(because it is not; push is a counterpart of fetch), and leave
push as is.
In a typical mothership-satellite configuration, I would
recommend a workflow like this:
On Mothership:
remote.satellite.url: satellite:project.git
remote.satellite.push: refs/heads/master:remotes/mothership/master
On Satellite:
remote.mothership.url: mothership:project.git
remote.mothership.fetch: refs/heads/master:remotes/mothership/master
So when you happen to be on the mothership and you would want to
sync the satellite (because you are tired of working at your
office and would want to continue on your satellite notebook
sitting on the couch, relaxed), you would push:
mothership$ git push satellite
Then you go to the satellite machine, and merge the mothership in:
satellite$ git merge mothership
If you forgot to push before leaving the mothership, you do not
have to worry; you can initiate the transfer from the satellite:
satellite$ git fetch mothership
and then do the same merge:
satellite$ git merge mothership
Of course you could do "git pull mothership" to do the above two
as a single step, but the point is then the "patch flow" would
always be the same no matter from which side you initiate the
transfer from mothership to satellite. The changes made on the
mothership will be done on 'master' branch on the mothership and
flow into remote/mothership/master on the satellite. And you
will merge changes from the mothership to the satellite always
via remotes/mothership/master tracking branch.
To go the other way, you would further define these two:
On Mothership:
remote.satellite.fetch: refs/heads/master:remotes/satellite/master
On Satellite:
remote.mothership.push: refs/heads/master:remotes/satellite/master
and "git push mothership" from satellite, or "git fetch
satellite" from the mothership.
Another reason not to do what you described inside git-push is
that you do not need to -- I think you should be able to do all
that from your update (or post-update) hook.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pushing to a non-bare repository
2007-02-03 3:26 ` Junio C Hamano
@ 2007-02-03 9:46 ` Simon 'corecode' Schubert
2007-02-03 19:42 ` Junio C Hamano
2007-02-03 19:48 ` Linus Torvalds
0 siblings, 2 replies; 6+ messages in thread
From: Simon 'corecode' Schubert @ 2007-02-03 9:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Steven Grimm, git
[-- Attachment #1: Type: text/plain, Size: 1185 bytes --]
Junio C Hamano wrote:
>> This keeps coming up as I introduce people to git. In previous
>> discussions, the conclusion often seems to be that users don't really
>> know what they want the semantics to be.
>
> I do not think that was the conclusion. My suggestion to you
> would be to stop thinking as if push is a converse of pull
> (because it is not; push is a counterpart of fetch), and leave
> push as is.
However, your suggestion does not help people who don't know better. Pushing into the HEAD branch of another repo breaks stuff there. Badly. This should be prevented, really.
I don't say "Push needs to behave like a fast forward pull", because that's wrong. You can't just change the workdir, possibly due to permissions problems. But push has to abort if you try to forward HEAD on the remote, except if it is bare, of course.
cheers
simon
--
Serve - BSD +++ RENT this banner advert +++ ASCII Ribbon /"\
Work - Mac +++ space for low €€€ NOW!1 +++ Campaign \ /
Party Enjoy Relax | http://dragonflybsd.org Against HTML \
Dude 2c 2 the max ! http://golden-apple.biz Mail + News / \
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pushing to a non-bare repository
2007-02-03 9:46 ` Simon 'corecode' Schubert
@ 2007-02-03 19:42 ` Junio C Hamano
2007-02-03 19:48 ` Linus Torvalds
1 sibling, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2007-02-03 19:42 UTC (permalink / raw)
To: Simon 'corecode' Schubert; +Cc: git
Simon 'corecode' Schubert <corecode@fs.ei.tum.de> writes:
> I don't say "Push needs to behave like a fast forward pull",
> because that's wrong. You can't just change the workdir,
> possibly due to permissions problems. But push has to abort
> if you try to forward HEAD on the remote, except if it is
> bare, of course.
You can tweak receive-pack.c::update() to do that, perhaps along
the lines of this.
---
diff --git a/receive-pack.c b/receive-pack.c
index 7311c82..ccd48e4 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -9,6 +9,7 @@
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
+static char *current_branch;
static int deny_non_fast_forwards = 0;
static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
@@ -115,6 +116,18 @@ static int update(struct command *cmd)
name);
}
+ if (!is_bare_repository()) {
+ /*
+ * Pusing into a live repository. updating .git/HEAD
+ * or the current branch is a no-no...
+ */
+ if (strncmp(name, "refs/", 5) ||
+ (current_branch && !strcmp(name, current_branch))) {
+ cmd->error_string = "update current";
+ return error("refusing to update the current branch '%s' in a live repository", name);
+ }
+ }
+
strcpy(new_hex, sha1_to_hex(new_sha1));
strcpy(old_hex, sha1_to_hex(old_sha1));
@@ -436,6 +449,13 @@ int main(int argc, char **argv)
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
+ if (!is_bare_repository()) {
+ unsigned char h[20];
+ const char *head = resolve_ref("HEAD", h, 0, NULL);
+ if (head && strcmp("HEAD", head))
+ current_branch = xstrdup(head);
+ }
+
write_head_info();
/* EOF */
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: Pushing to a non-bare repository
2007-02-03 9:46 ` Simon 'corecode' Schubert
2007-02-03 19:42 ` Junio C Hamano
@ 2007-02-03 19:48 ` Linus Torvalds
2007-02-03 21:18 ` Junio C Hamano
1 sibling, 1 reply; 6+ messages in thread
From: Linus Torvalds @ 2007-02-03 19:48 UTC (permalink / raw)
To: Simon 'corecode' Schubert; +Cc: Junio C Hamano, Steven Grimm, git
On Sat, 3 Feb 2007, Simon 'corecode' Schubert wrote:
>
> However, your suggestion does not help people who don't know better. Pushing
> into the HEAD branch of another repo breaks stuff there. Badly. This should
> be prevented, really.
No, please don't break it. I do it all the time.
I just do "git push remote".
And then eventually on the remote end I do end up having to "update", but
that's a simple "git checkout -f".
It's actually really convenient. It works even if the remote end had
dirty stuff in their tree, and "git diff" still works (because the push
didn't update the index), and a simple "git diff HEAD" shows that "oops,
we're not up-to-date".
Yeah, I guess it's a bit error-prone ("Why does 'git log' say I have a new
version, but the working tree doesn't seem new?"), but it actually does
work.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pushing to a non-bare repository
2007-02-03 19:48 ` Linus Torvalds
@ 2007-02-03 21:18 ` Junio C Hamano
0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2007-02-03 21:18 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Simon 'corecode' Schubert, Steven Grimm, git
(sorry, resending to avoid vger spam filter)
Linus Torvalds <torvalds@linux-foundation.org> writes:
> On Sat, 3 Feb 2007, Simon 'corecode' Schubert wrote:
>>
>> However, your suggestion does not help people who don't know better. Pushing
>> into the HEAD branch of another repo breaks stuff there. Badly. This should
>> be prevented, really.
>
> No, please don't break it. I do it all the time.
>
> I just do "git push remote".
>
> And then eventually on the remote end I do end up having to "update", but
> that's a simple "git checkout -f".
I do not think anybody is disputing the fact that the current
git-push does work as expected.
But expectation is a relative thing. The current behaviour is
likely to confuse new people; it is like a sharp-edged razor
that can cut through fingers if the user does not know which end
is the handle and which end is the blade.
I sent a "if Simon wanted to do it, it is simple" concept patch,
but obviously Simon or anybody can do the same check in the
update hook if needed. However, that would make the newbie
safety opt_in, and there inevitably will come a discussion on
what should be the default.
And I suspect that the recent trend is that people would want
the default to be more newbie friendly, while leaving an opt_in
escape hatch for power-user convenience. Obviously my patch
does not have that escape hatch, and as such it is not meant for
inclusion as-is.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-02-03 21:18 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-03 3:01 Pushing to a non-bare repository Steven Grimm
2007-02-03 3:26 ` Junio C Hamano
2007-02-03 9:46 ` Simon 'corecode' Schubert
2007-02-03 19:42 ` Junio C Hamano
2007-02-03 19:48 ` Linus Torvalds
2007-02-03 21:18 ` Junio C Hamano
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).