1

I have a git-svn repository (Unexpected merge error in a git svn system?); it has a remote called origingit referring to another git repo, in addition to git-svn which refers to an SVN repo.

$ git branch -a
* master
  remotes/git-svn
$ git remote show 
origingit
$ tree .git/refs/{heads,remotes}
.git/refs/heads
└── master
.git/refs/remotes
├── git-svn
└── origingit

Here is the problem: when I do

git pull --rebase origingit master

... git splits the tree, so that all commits from origingit that have not been part of the original git svn clone lose their git-svn-id (are "local", see git-svn-id is missing from some commits); in this case, the relevant commits look like this (they all have "null edit" in the name):

$ git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order | grep 'null edit'
* cae158d (git-svn) : null edit A06
* 8f79edf : null edit A05
* 0c7373e : null edit A04
* b4bf336 : null edit A03
* e05cfc6 : null edit A02
| * e0c6823 (HEAD, master) : null edit A07
| * 03ed433 : null edit A06
| * de3bd53 : null edit A05
| * 65bf738 : null edit A04
| * 62ab3f6 : null edit A03
* | 964b300 : null edit A01
| * 14f5aba : null edit A02
| * f0ef194 : null edit A01

Note that master has picked up the latest "null edit A07", which came in from origingit.

When I do

git svn rebase

... all those commits present in the SVN repository should get a git-svn-id, and those not yet comitted to SVN don't - but are listed after (in time, or first in order) the git-svn-id ones in git log; so on the next git svn dcommit, those local would be comitted to SVN. However, in this particular case, I get the log --graph as:

* cae158d (HEAD, git-svn, master) : null edit A06
* 8f79edf : null edit A05
* 0c7373e : null edit A04
* b4bf336 : null edit A03
* e05cfc6 : null edit A02
* 964b300 : null edit A01

In fact, here git svn rebase outputs to stdout just "First, rewinding head to replay your work on top of it..." and exits; otherwise, it usually says "Applying: ..." which apparently refers to patches (and ... is the commit message for those local), and in that case, the expected log would be:

* xxxxxxx (HEAD, master) : null edit A07
* cae158d (git-svn) : null edit A06
* 8f79edf : null edit A05
* 0c7373e : null edit A04
* b4bf336 : null edit A03
* e05cfc6 : null edit A02
* 964b300 : null edit A01

So - even if null edit A07 is clearly a valid commit in the origingit repo, and comes after null edit A06 one (which is also present in SVN), git svn rebase fails to apply this patch. Why - and how is it even possible?

In any case, from this point, I can do git pull --rebase ... and get to the previous state shown.

Here it would be very nice if there was some debugging facility, which could tell you how git rebase goes through each commit and decides what to do - but unfortunately, --verbose just dumps a list of files changed between the last git-svn-id commit and the latest HEAD, so it doesn't help much.

Adding some printouts to /usr/lib/git-core/git-svn, I could see that git svn rebase ultimately calls git rebase refs/remotes/git-svn; so I tried to add interactive to it:

$ git pull --rebase origingit master
...
$ git rebase --interactive  refs/remotes/git-svn

... and it shows:

noop

# Rebase cae158d..e0c6823 onto cae158d
#
# Commands: [...]

So, applying patches doesn't happen during rebase, because it doesn't find that any patches should be made. But how is that possible - noting that cae158d is the SHA of "null edit A06" within git-svn (and is present both on SVN and in origingit), while e0c6823 is the SHA of "null edit A07" which came in from origingit - where it stands unequivocally and without a problem as a commit (meaning, there must be an actual change from previous revision) after the "null edit A06"??

So, how can I inspect why this happens - and ultimately, how can I force git to recognize during git svn rebase that there is indeed a patch there?

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • Just a note: there is a [GIT_TRACE environment variable](https://www.kernel.org/pub/software/scm/git/docs/#_environment_variables) that does reveal a lot, but I best I could get to is `built-in: git 'format-patch' '-k' '--stdout' '--full-index' '--ignore-if-in-upstream'`; apparently it is `--ignore-if-in-upstream` that makes the patch not appear; however, as `format-patch` is built-in, it cannot be traced further with this method... – sdaau Mar 16 '15 at 04:11

0 Answers0