Hello, One of our users had this come up today. He (on a different branch) did a push (successfully) earlier today. Upon pushing some more changes this afternoon in the "Task/4919..." branch, the following message was received: -- [caleb@neon VOS4]$ git push Enter passphrase for key '/home/caleb/.ssh/id_rsa': To ssh://git@code.izrm.com/~/WhiteBoot4/VOS4-NEW ! [rejected] Issue/Default -> Issue/Default (non-fast forward) ! [rejected] Issue/Task_4831_MUP_Survey_Layout -> Issue/Task_4831_MUP_Survey_Layout (non-fast forward) ! [rejected] Task/4872-MUP-APlan-promotion -> Task/4872-MUP-APlan-promotion (non-fast forward) <snip> error: failed to push to 'ssh://git@code.izrm.com/~/WhiteBoot4/VOS4-NEW' -- However the branch in question was pushed successfully (despite the error message). * Task/4919-MUP-Agent-ID-promotion 7e80ca6 origin/Task/4919-MUP-Agent-ID-promotion 7e80ca6 As far as I can tell, most (if not all) of the branches that were rejected were not changed today. Any ideas or pointers for where I should look to resolve this? ** git version 1.5.4.1 ** -- Best Regards, Jason Garber Senior Systems Engineer IonZoft, Inc. (814) 941-2390 jgarber@ionzoft.com -
I think the user is missing one fundamental aspect of pushing: the behavior of "git push" without any refspecs specified is to push all matching refs (i.e., if you have branch refs/heads/Issue/Default and so does the remote, then it will attempt to push). So no matter what branch he is on when doing the push, it tries to push many such branches. If you want to push just the current branch, try: These branches are rejected because he has local branches of the same name that are _behind_ where the remote is. In other words, pushing would roll back history, and therefore these pushes are rejected without the '-f' option to force. These branches get in this state through something like: # check out a local branch to match an upstream branch git checkout -b Issue/Default origin/Issue/Default # now hack on it or whatever hack hack hack build build build # and we're finished, so let's go back to another branch git checkout Task/4919... # time passes, and somebody else pushes changes to Issue/Default And now at this point the user's Issue/Default is behind the remote's. Yes, presumably that was in your <snip> section above. The "error:" message is reported if pushing _any_ branch fails or is rejected. If you are interested in pushing only the one branch, then you need to say so explicitly. -Peff -
git-push(1) is a bit confusing I think: "Note: If no explicit refspec is found, (that is neither on the command line nor in any Push line of the corresponding remotes file---see below), then all the heads that exist both on the local side and on the remote side are updated." is clear enough, but then: "--all Instead of naming each ref to push, specifies that all refs under $GIT_DIR/refs/heads/ be pushed." So what is '--all' needed for then? It seems like the default should be to push just the current branch ... this would correspond to what a user of git pull expects (even though the converse of git-push is really git-fetch, for a new user, that might not be entirely clear). j. -
In the first case we push "matching" refs: any head which already exists on both sides. In the second case, we push all heads which exist on the sending send, whether or not a matching ref already exists on the remote side. I think the first statement could be made to emphasize the matching aspect a little more, since a quick read makes it seem like it's pushing I agree with you, but others do not; this has come up several times in the past (there was some discussion a week or two ago in the thread "Minor annoyance with git push"). -Peff -
I'd like to nominate you to rewrite all of the git documentation from Sounds like an opportunity for a config option. j. -
Doh! This is why nobody writes clear explanations: it gets you nominated Again I agree, though I think there is some resistance to that (see the thread I mentioned). Junio's opinion seems to be "why can't they just use 'git push <remote> HEAD'?" (and he suggested a 'git push HEAD' shorthand syntax, as well). But then, nobody has put forth a patch, so I think if you wanted to argue it, the best way would be to do so (though I think it would be rejected, it would give those who wanted to try it something to play with). -Peff -
Hi, No good deed goes unpunished, they used to say. Ciao, Dscho -
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> --- On Tue, 19 Feb 2008, Jeff King wrote: > On Tue, Feb 19, 2008 at 10:18:09AM -0500, Jay Soffian wrote: > > > > It seems like the default should be to push just the > > > > current branch ... this would correspond to what a user of > > > > git pull expects (even though the converse of git-push is > > > > really git-fetch, for a new user, that might not be > > > > entirely clear). > > > > > > I agree with you, but others do not > > > > Sounds like an opportunity for a config option. > > Again I agree, though I think there is some resistance to that > (see the thread I mentioned). Junio's opinion seems to be "why > can't they just use 'git push <remote> HEAD'?" (and he suggested > a 'git push HEAD' shorthand syntax, as well). FWIW I would resist, just because that config option would change the _semantics_ of a git program. Just think about the IRC channel. "How do I update only HEAD?" -- "Just say 'git push'" -- "No, that updates nothing" -- "Well, works here" -- "But not here!" ... "Can _nobody_ help me?" Having inconsistent semantics is wrong, wrong, wrong. > But then, nobody has put forth a patch, so I think if you wanted > to argue it, the best way would be to do so (though I think it > would be rejected, it would give those who wanted to try it > something to play with). This is a tongue-in-cheek patch. Just so that nobody can say that there were no patches. builtin-push.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/builtin-push.c b/builtin-push.c index c8cb63e..7bcb141 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -134,6 +134,14 @@ int cmd_push(int argc, const char **argv, const char *prefix) flags |= TRANSPORT_PUSH_ALL; if (mirror) flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE); + if (!all && argc < 2) + warning("Pushing without branch names is deprecated.\n" + "Too many users ...
+ if (!all && argc < 2) + warning("Pushing without branch names is deprecated.\n" + "Too many users just assumed what it should do\n" + "according to them, got burned, and blamed us,\n" + "the good git developers.\n\n" + "So everybody has to suffer now, and get used to\n" + "new semantics.\n\n" + "Thank you for your time.\n"); Quite accurate... lol. -
Hi, Heh. FWIW I think I might just go on with that patch, until those who _should_ care deeply enough about it shut me up with code... Note that even if I vent here a bit, there's a good side to it: my patch should be a good start (actually, I think it is more than just a start, but hey, it's not like I want my patch to _really_ go into mainline). This is my current state: Documentation/git-push.txt | 16 +++++++++++++--- builtin-push.c | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 5f24944..d373d05 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -9,8 +9,10 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- [verse] -'git-push' [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] - [--repo=all] [-f | --force] [-v | --verbose] [<repository> <refspec>...] +'git-push' [--all] [-m | --matching] [--dry-run] [--tags] + [--receive-pack=<git-receive-pack>] + [--repo=all] [-f | --force] [-v | --verbose] + [<repository> <refspec>...] DESCRIPTION ----------- @@ -49,7 +51,8 @@ Note: If no explicit refspec is found, (that is neither on the command line nor in any Push line of the corresponding remotes file---see below), then all the heads that exist both on the local side and on the remote -side are updated. +side are updated. This behavior is DEPRECATED and will go +away in the future. Use the `--matching` option in the future. + `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`. + @@ -63,6 +66,13 @@ the remote repository. Instead of naming each ref to push, specifies that all refs under `$GIT_DIR/refs/heads/` be pushed. +-m, \--matching:: + Push all refs that are present both locally and remotely. + This used to be the default action if no ref was specified, + until a few users who cannot read man pages prevailed ...
Heh. It is a good sign that git has made the patch-generation workflow so pleasant to use that we are willing to make patches for the sake of You forgot to add a "--matching" option in case people want to explicitly request the old behavior. ;P Seriously, though, I think it is not just new users. It is that for some (many? most?) people, wanting to push just the HEAD is the _normal_ workflow. So they must remember to always say "git push origin HEAD", and if they ever forget, the side effects are non-trivial to clean up. -Peff -
Hi, The point is: if that becomes the default (with a certain config option), people will get used to typing "git push". They will not even _know_ See followup. BTW if that is really the way to go, we will have to have a _long_ period (I am talking about 6-12 _months_ if not more) where there _must not_ be a default action for git-push. Otherwise people _will_ get more confused than necessary. Ciao, Dscho -
I guess I hoped that people giving answers on the IRC channel would be a I agree that it would need a long deprecation period to change behavior. It would almost be easier to have a "git <foo>" command where <foo> is some sort of restricted, safe-for-certain-workflows version of push. -Peff -
For those interested, this is how I plan to have the default for pyrite. The default currently just calls "git push origin HEAD" Calling with another target repository and refspec would still be supported of course. In general, the plan it to take the most common work flows and simply the UI around those. This includes silently doing "git add -u" before pushing a commit and "pyt diff" will diff between the working directory and HEAD because I have never been interested in the state of the index, only in the state of the working dir. -Govind -
For both counts, it feels so much like Cogito. I would not comment on "the most common" adjective, but I am still a big believer of "core git gives common foundation for Porcelains that support different workflows to talk with each other" ideal, and I really like that you are building a Porcelain that would suit your favorite workflow. -
Once I have it in better shape, I hope to get commentary from the rest of the git users on how their workflows go and see where I can simplify things or where they need to be more complex. I don't want it to _just_ be for my workflow. I want something that appeals to the common user (if there is such a thing, and with git, I don't know that you can say that). -Govind -
Oh, I did not mean "your private workflow that is not common to anybody else". That's certainly useless and there is no reason I would have said "I really like" to something like that (on the other hand, of course I would not stop such an attempt either). That's why I said "your _favorite_ workflow". Your favorite could certainly be shared by other people. -
[alias] mypush = push origin HEAD j. -
