{"thread":{"id":"22141","subject":"Re: git-svn: git svn dcommit doesn't handle network failure","startedAt":"2010-01-09T01:00:58Z","lastAt":"2010-01-09T07:57:43Z","messageCount":3,"participants":["Jonathan Nieder","Eric Wong"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"131156","messageId":"20100109010058.GA11922@progeny.tock","threadId":"22141","inReplyTo":"20091122112434.29914.59452.reportbug@localhost.localdomain","subject":"Re: git-svn: git svn dcommit doesn't handle network failure","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-01-09T01:00:58Z","receivedAt":"2010-01-09T01:00:58Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Eric,\n\n'git svn dcommit' does not seem to have any error recovery built in,\nso the user is put in a not-great situation if the network cable is\npulled in the middle, as in the report below.\n\nSee also <http://thread.gmane.org/gmane.comp.version-control.git/70458>\n\nIdeally, it would be nice if users could pretend that each push of\na single commit is an atomic operation that rewrites the corresponding\nlocal commit at the same time.  In other words, to clean up we might\nunapply the unpushed patch, then run rebase_cmd().\n\nWhat do you think?\n\nBrice Goglin wrote:\n\n> Package: git-svn\n> Version: 1:1.6.5-1\n> Severity: important\n> \n> Hello,\n> \n> If the network fails during dcommit, git svn gets totally screwed up.\n> It will give you the prompt back with HEAD pointing to the last SVN-pushed\n> commit, and the next one applied and not git-committed.\n> \n> $ git svn dcommit\n> Committing to svn+ssh://bgoglin@scm.gforge.inria.fr/svn/knem/branches/rma ...\n> \tM\tcommon/knem_io.h\n> Committed r237\n> \tM\tcommon/knem_io.h\n> r237 = f839e16b94052f8b71aa4b66124b37a8337182e0 (refs/remotes/rma)\n> No changes between current HEAD and refs/remotes/rma\n> Resetting to the latest refs/remotes/rma\n> Unstaged changes after reset:\n> M\tcommon/knem_io.h\n> M\tdriver/linux/knem_main.c\n> ssh: connect to host scm.gforge.inria.fr port 22: Connection timed out\n> Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/SVN/Core.pm line 584.\n> Network connection closed unexpectedly:  at /usr/lib/git-core/git-svn line 557\n> \n> \n> Now the only way I found to solve this mess is to git-reset --hard,\n> git checkout the old HEAD again, and git svn dcommit the remaining stuff.\n> \n> The big problem is that I don't see any easy way to find the old HEAD.\n> I had to look back in my terminal history in case there's still the output\n> of a git log showing the old HEAD commitid.\n> \n> I don't know how dcommit works internally, but my feeling is that it\n> should go to a new temporary branch during dcommit. This way, we would\n> just have to checkout the non-temporary branch on failure. For now,\n> I do it manually in case the SVN server fails again, but that's really\n> annoying.\n> \n> thanks,\n> Brice\n"},{"id":"131161","messageId":"20100109021347.GA26520@dcvr.yhbt.net","threadId":"22141","inReplyTo":"20100109010058.GA11922@progeny.tock","subject":"Re: git-svn: git svn dcommit doesn't handle network failure","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2010-01-09T02:13:47Z","receivedAt":"2010-01-09T02:13:47Z","isPatch":false,"sender":{"key":"e@80x24.org","avatar":null},"body":"Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Hi Eric,\n> \n> 'git svn dcommit' does not seem to have any error recovery built in,\n> so the user is put in a not-great situation if the network cable is\n> pulled in the middle, as in the report below.\n> \n> See also <http://thread.gmane.org/gmane.comp.version-control.git/70458>\n> \n> Ideally, it would be nice if users could pretend that each push of\n> a single commit is an atomic operation that rewrites the corresponding\n> local commit at the same time.  In other words, to clean up we might\n> unapply the unpushed patch, then run rebase_cmd().\n> \n> What do you think?\n\nHi Jonathan,\n\nI agree that error recovery for dcommit sucks right now.\n\nI think Brice's idea (creating a temporary branch to dcommit from)\nis easier to implement and less likely to break than automatically\nunapplying patches.\n\nNot sure when I'll have time to implement this, but I'll accept\npatches in the mean time.\n\n> Brice Goglin wrote:\n> \n> > Package: git-svn\n> > Version: 1:1.6.5-1\n> > Severity: important\n> > \n> > Hello,\n> > \n> > If the network fails during dcommit, git svn gets totally screwed up.\n> > It will give you the prompt back with HEAD pointing to the last SVN-pushed\n> > commit, and the next one applied and not git-committed.\n> > \n> > $ git svn dcommit\n> > Committing to svn+ssh://bgoglin@scm.gforge.inria.fr/svn/knem/branches/rma ...\n> > \tM\tcommon/knem_io.h\n> > Committed r237\n> > \tM\tcommon/knem_io.h\n> > r237 = f839e16b94052f8b71aa4b66124b37a8337182e0 (refs/remotes/rma)\n> > No changes between current HEAD and refs/remotes/rma\n> > Resetting to the latest refs/remotes/rma\n> > Unstaged changes after reset:\n> > M\tcommon/knem_io.h\n> > M\tdriver/linux/knem_main.c\n> > ssh: connect to host scm.gforge.inria.fr port 22: Connection timed out\n> > Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/SVN/Core.pm line 584.\n> > Network connection closed unexpectedly:  at /usr/lib/git-core/git-svn line 557\n> > \n> > \n> > Now the only way I found to solve this mess is to git-reset --hard,\n> > git checkout the old HEAD again, and git svn dcommit the remaining stuff.\n> > \n> > The big problem is that I don't see any easy way to find the old HEAD.\n> > I had to look back in my terminal history in case there's still the output\n> > of a git log showing the old HEAD commitid.\n> > \n> > I don't know how dcommit works internally, but my feeling is that it\n> > should go to a new temporary branch during dcommit. This way, we would\n> > just have to checkout the non-temporary branch on failure. For now,\n> > I do it manually in case the SVN server fails again, but that's really\n> > annoying.\n> > \n> > thanks,\n> > Brice\n> --\n"},{"id":"131176","messageId":"20100109075743.GA3377@progeny.tock","threadId":"22141","inReplyTo":"20100109021347.GA26520@dcvr.yhbt.net","subject":"Bug#557477: git-svn: git svn dcommit doesn't handle network failure","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-01-09T07:57:43Z","receivedAt":"2010-01-09T07:57:43Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Eric Wong wrote:\n\n> I agree that error recovery for dcommit sucks right now.\n> \n> I think Brice's idea (creating a temporary branch to dcommit from)\n> is easier to implement and less likely to break than automatically\n> unapplying patches.\n\nSounds sane to me.  Probably that temporary branch could just be\na detached HEAD.\n\nCurrent dcommit:\n\n diff-index --quiet HEAD || carp \"Cannot dcommit with a dirty index\"\n if head ne 'HEAD':\n\tsave the old HEAD\n\tcheck out the head\n find svn upstream\n decide what commits to push (linearize_history)\n for each commit d to push:\n\tcommit diff from d~ to d to the remote repository\n\t\t(this involves applying the diff locally?)\n\tremember parents\n\tfetch remote revision, using remembered parents for commit\n\n\tunless args include --no-rebase:\n\t\trebase the current HEAD against fetched revision\n\t\t\t(or reset if there are no changes)\n\t\tupdate the list of commits to push\n if head ne 'HEAD':\n\tlet the user know the branch or commit id for the finished dcommit\n\tcheck out the old head again\n\nIf I understand you correctly, before finding the svn upstream,\ndcommit would save the HEAD ref name (if any) and detach the HEAD;\nafter pushing the relevant commits, update that ref and reattach the\nHEAD.\n\nIf pushing fails early, what should git-svn do?  Leave the HEAD\ndetached, with a message suggesting to return to the old ref?  Check\nout the old ref, with a message suggesting to 'git svn rebase' and try\nagain?  Do the 'git svn rebase' automatically?\n\nI guess the safest option is the first one.  That would at least be a\nstarting point for experimenting with more friendly behaviors.\n\nI should also mention that there seems to be a little race here: if\ngit-svn dies before (or while) fetching the newly commited revision,\nwhen it is fetched later it will have the wrong parents.\n\nJonathan\n"}]}