0

Ok, I have a bit of a convoluted setup, where I use git version 1.7.9.5, and have a git repository, which on the git side is a clone of a bare repo; and on the svn side, should be a clone of a remote SVN repository. On the other hand, there are no branches, and everything is done in master.

The remote repository was offline for a while; it just came back, and I seemingly managed to upload all outstanding commits via git svn dcommit.

The problem is now, I tried making a new change/commit after this; and seemingly dcommit wants to upload the wrong file - and fails with 'Transaction out of date'; I saw How to recover from an unwanted rename using git-svn: "Transaction is out of date", but that doesn't seem to answer this.

The setup is somewhat like this:

$ git config -l
svn-remote.svn.url=svn+ssh://user@myserver/remotepath/to/repo_svn
svn-remote.svn.fetch=:refs/remotes/git-svn
..
remote.origingit.url=file:///local/path/to/repo_bare.git
remote.origingit.fetch=+refs/heads/*:refs/remotes/origingit/*

Then I pull from the local bare repo git:

$ git svn fetch
user@myserver's password: 
$ git pull --rebase origingit master
From file:///local/path/to/repo_bare
 * branch            master     -> FETCH_HEAD
Current branch master is up to date.

$ git status -uno
# On branch master
nothing to commit (use -u to show untracked files)

I check to see if there is a difference from the SVN version:

# https://stackoverflow.com/questions/2426654/git-svn-status-showing-changes-that-are-not-committed-to-svn

$ git diff git-svn HEAD
diff --git a/folder/file.tex b/folder/file.tex
index 7201cc7..3df14bc 100644
--- a/folder/file.tex
+++ b/folder/file.tex
@@ -299,7 +299,7 @@ Test


-%  test
+% test
 % still testing

$ git diff --name-status remotes/git-svn
M       folder/file.tex

... and there is - and it is the right change, in the file folder/file.tex; so I'm trying to push/upload that to svn using dcommit:

$ git svn dcommit --verbose
Committing to svn+ssh://user@myserver/remotepath/to/repo_svn ...
user@myserver's password: 
    M   notes.txt
Transaction is out of date: File '/notes.txt' is out of date at /usr/lib/git-core/git-svn line 922

Now, the file I expected to be uploaded is ./folder/file.tex; yet git svn dcommit tries to upload ./notes.txt - which indeed, does exist, but there haven't been changes to it in this commit?!

Interestingly, if I do here:

$ git svn rebase 
user@myserver's password: 
First, rewinding head to replay your work on top of it...
$ git diff --name-status remotes/git-svn
$ git svn dcommit 
Committing to svn+ssh://user@myserver/remotepath/to/repo_svn ...
$ 

... that is if I do git svn rebase instead of git svn fetch first, then there are no differences recognized between the git side and the svn side, and thus I can get nothing dcommited (and so I don't even get a password prompt). EDIT: note that if I do git pull --rebase origingit master after the git svn rebase, the same as before happens (i.e. git diff --name-status sees the right change, but git svn dcommit fails with "Transaction is out of date:")

So my question is - why does git svn dcommit insist on uploading this wrong file (in case git svn fetch is ran first) - instead of the right file, which is otherwise correctly reported by git diff --name-status ?? How can I inspect that?

And how can I force git svn to correctly synchronize the local git changes to the remote SVN?

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278

1 Answers1

0

EDIT: found this: git-svn-id is missing from some commits - and it seems it helped; the trick is to use fetch for both git svn and git as described there; and then use cherry-pick for leftover commits that need to be dcommited; apparently this business with being "stuck" at rev 60 is due to that revision being the last that had a proper git-svn-id:


I got somewhere, but didn't solve it; but may answer partially why is that wrong file committed.

After a git svn rebase, I have:

$ git svn info
...
Revision: 446
...
Last Changed Rev: 446

git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order
* aaaa100 (HEAD, git-svn, master) : null edit - 
* aaaa099 : some more testing
* aaaa098 : some testing
* aaaa097 : just testing
...

Note that revision is the latest (446) here, and the log basically shows a "straight" line all the way through.

After doing git pull --rebase origingit master, I get:

$ git svn info
...
Revision: 60
...
Last Changed Rev: 60

git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order | less

* aaaa100 (git-svn) : null edit - 
* aaaa099 : some more testing
...
* aaaa030 some early commit
* aaaa029 : early commit
* aaaa028 : old commit
| * bbbb101 (HEAD, master) : another null edit; previous attempt failed, 
| * bbbb100 : null edit - 
| * bbbb099 : some more testing
...

| * bbbb030 some early commit
| * bbbb029 : early commit
| * bbbb028 : old commit
* | aaaa027 : very old commit
| * bbbb027 : very old commit

So here, the log is more accurate, as it visualizes the differences between the svn and the git logs properly (i.e. svn and git are interleaved at bottom, when server was working, and git and svn commits are consecutive; then there is a break where commits are sequential due to server being offline) - and correctly shows the new revision; BUT for some reason it also thinks it is at a very early SVN revision (60) - making it want to send the files which were modified in that revision; so probably the reason for the wrong file. (hashes are changed for readability)

I saw a bit /usr/lib/git-core/git-svn - it seems that it uses some sort of git commands to calculate the revision number, but cannot get much more out of that Perl code at the moment.

Note that git pull without --rebase resulted with this:

$ git pull origingit master
From file:///local/path/to/repo_bare
 * branch            master     -> FETCH_HEAD
Auto-merging folder/file.tex
CONFLICT (add/add): Merge conflict in folder/file.tex
Automatic merge failed; fix conflicts and then commit the result.

So I looked into How to handle/fix git add/add conflicts?, and ultimately tried:

$ git pull --strategy=subtree origingit master
From file:///local/path/to/repo_bare
 * branch            master     -> FETCH_HEAD
Merge made by the 'subtree' strategy.
 folder/file.tex |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

This might look ok, but it isn't - it doesn't just copy the bbbb101 another null edit; previous attempt failed commit; it makes a merge based on it; so now I have:

$ git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order | less
*   9579e8b (HEAD, git-svn, master) Merge branch 'master' of file:///local/path/to/repo_bare
|\  
* | aaaa100 : null edit - 
...

which is absolutely not what I wanted; and the subsequent attempt to repeat the procedure failed with:

Applying: : second commit after git transition (first failed a bit)
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging notes.txt
CONFLICT (content): Merge conflict in notes.txt
Failed to merge in the changes.
Patch failed at 0001 : second commit after git transition (first failed a bit)

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".

So again it reverted to the old SVN revision, and caused a mess - well, this is what I hoped I'd avoid, and didn't; not sure what to do now ...

Community
  • 1
  • 1
sdaau
  • 36,975
  • 46
  • 198
  • 278