2015-01-15 11 views
5

Ich benutze git-svn, um einen Klon eines freigegebenen Subversion-Repository zu halten. Kürzlich hat jemand die Commit-Nachricht einer Revision bearbeitet (a lathis SO question) nachdem ich git svn fetch ed diese Revision hatte. Wie kann ich meinen Git-Klon korrigieren, um die korrekte Commit-Nachricht zu erhalten?Reparatur git-svn Repository nach der historischen Subversion Revision geändert

Ich hatte erwartet, git svn reset gefolgt von git svn fetch, um dieses Commit zu holen und die Dinge zu aktualisieren, so dass ich nur meine lokalen Niederlassungen reparieren muss, aber das scheint eigentlich nichts zu tun; Die git svn fetch ruft die Commits, auf die ich zurückgesetzt habe, nicht erneut ab.

(Ja, ich denke, die Änderung der Commit-Nachricht eine schlechte Idee war, aber das ist nicht etwas, was ich haben die Kontrolle über.)

aktualisieren: Ich habe versucht, den Prozess, der (in der Tat vorgeschlagen sleske, hatte ich versucht, bevor ich die Frage gestellt habe, aber ich habe es gerade für den Fall nochmal versucht), aber ohne Glück. Ich erhalte eine Ausgabe wie die folgende Liste:

[email protected] ~/code ((358a2dd...)) Fri 16 Jan 15:31:27 
$ git svn reset -p 55102 
r55094 = 25d126219f7eeddfc7d0842704c7efcc0443dd70  (refs/remotes/origin/branchname) 

[email protected] ~/code ((358a2dd...)) Fri 16 Jan 15:33:06 
$ git svn fetch 

[email protected] ~/code ((358a2dd...)) Fri 16 Jan 15:33:08 
$ 

Es von git svn fetch keine Ausgabe ist (oder es ist, wenn es verpflichtet ist seit ich das letzte Mal lief, aber es ist nur die neuen Commits zu holen, nicht Erneutes Abrufen die alten) und insbesondere gibt es keine rereading Nachricht wie in sleskes Beispiel.

Falls es relevant ist, verwende ich Git v2.0.4.

Update 2: redigiert Leicht .git/config unter:

[core] 
    repositoryformatversion = 0 
    filemode = true 
    bare = false 
    logallrefupdates = true 
[svn-remote "svn"] 
    url = http://server/repos/repo 
    fetch = trunk:refs/remotes/origin/trunk 
    branches = branches/*:refs/remotes/origin/* 
    tags = tags/v10/*:refs/remotes/origin/tags/* 
    tags = tags/v11/*:refs/remotes/origin/tags/* 
    tags = tags/v12/*:refs/remotes/origin/tags/* 
    tags = tags/v13/*:refs/remotes/origin/tags/* 

Ich werde nicht die volle Leistung von git branch -avv veröffentlichen, weil es viel es ist, aber das ist, wo es wirklich interessant wird, so dass ich Ich werde eine Liste von allem, was ich getan habe:

  1. Ich hatte einen Checkout von einem anderen Zweig als der Zweig mit dem Fehler. Running git svn reset machte keinen Unterschied: remotes/origin/branchname weiterhin auf eine neuere Commit zeigen. Es überrascht nicht, git svn fetch hat nichts getan.

  2. Ich ausgecheckt remotes/origin/branchname und lief wieder git svn reset. Dies funktionierte: remotes/origin/branchname wies auf das Elternteil der Duff Commit.

  3. Ich lief git svn fetch. Das hat absolut nichts getan: keine Commits wurden geholt und remotes/origin/branchname hat sich nicht bewegt.

  4. Ich habe ein paar Dummy-Commits auf diesem Zweig im Subversion-Repository erstellt (eins fügte eine leere Datei hinzu, das nächste löschte es wieder), dann lief git svn fetch again.

    Hier wird es wirklich komisch: das Duff-Commit wurde nicht referenziert. Stattdessen hat der Abruf, der beim Commit gestartet wurde, wo ich die Dummy-Datei hinzugefügt habe, einen "Index-Mismatch" im Prozess gemeldet. Runing git show auf das Commit, das die Dummy-Datei hinzugefügt hat, zeigt es mit allen Diffs zwischen dem Commit, auf das ich zurückgesetzt habe und dem Dummy verpflichten.

    Nun git log --graph --decorate --pretty=oneline --abbrev-commit HEAD origin/branchname läuft wie folgt aussieht:

    * 7b12bbc (origin/branchname) Remove dummy file 
    * 730c2ab Add dummy file # But `git show 730c2ab` includes the diffs between b89af06 and 93920f9 as well 
    | * 93920f9 (HEAD) Uninteresting commit 
    | * 91c7163 Uninteresting commit 
    | * ce51022 Commit with the changed commit message 
    |/ 
    * b89af06 Uninteresting commit 
    

    Beachten Sie, dass, anders als HEAD gibt jetzt nichts zu einigen der Commits auf diesem Zweig zeigt ist.

ich komme schnell zu dem Schluss, dass ein Fehler ist zumindest einfach in git svn einen Teil dieses Verhaltens. Sicherlich ist das, was ich oben in Punkt 4 gesehen habe, nichts, was zumindest nach meinem Verständnis passieren sollte.

+0

Konnten Sie posten: a) den Inhalt von ".git/config" (wo die git-svn Remote konfiguriert ist), und b) die Ausgabe von 'git branch -avv' vor und nach dem Aufruf von' git svn reset ... '. Letzteres sollte zeigen, was mit dem von "git svn" verwendeten Remote-Tracking-Zweig passiert. – sleske

+0

@sleske Ich habe die '.git/config' wie gewünscht hinzugefügt, und ein bisschen Graben basierend auf der Ausgabe von' git branch -avv' gemacht. Es ist * sehr merkwürdig *. –

+1

Ja, sehr seltsam und ziemlich wahrscheinlich ein Fehler in 'git svn'. Ich befürchte, dass Sie, um mehr Hilfe zu bekommen, einen reproduzierbaren Testfall bereitstellen müssen. Sie könnten versuchen, ein Skript zu erstellen, das ein lokales SVN Repo erstellt, und es dann über 'git svn' auscheckt. Wenn Sie das gleiche Repo-Layout und die gleichen Optionen verwenden und strukturell ähnliche Commits erstellen, können Sie das Problem möglicherweise reproduzieren. – sleske

Antwort

1

git svn reset ist in der Tat der richtige Weg, es zu tun. Unter der Annahme, SVN Revision 4711 geändert wurde, sind die Schritte:

1) Verwerfen die geänderten SVN-Revision (und alles, was danach):

$ git svn reset -p 4711 
r1 = 18614es3df44c30da07 (refs/remotes/git-svn) 

2) Fetch die geänderte Version:

$ git svn fetch 
rereading 18614es3df44c30da07 
     A  trunk/a 
r4711 = 8dfb7d0758dbbc1d06004 (refs/remotes/git-svn) 
     A  trunk/b 
r4712 = e7337af3743e48c90ef3fa09906378b95997314c (refs/remotes/git-svn) 
[...] 

3) Jetzt sind die Daten von git-svn repariert. Sie müssen immer noch Ihre lokalen Niederlassungen reparieren. Wenn zum Beispiel Master den SVN trunk verfolgt, laufen:

git rebase remotes/git-svn 

(wo "Fernbedienungen/git-svn" ist der Remote-Tracking-Zweig von git svn erstellt - es kann einen anderen Namen haben).

Dies wird sehr gut in der git svn manpage, im Abschnitt auf den Unterbefehl "Reset" erklärt.

+0

Dies ist genau das, was ich ursprünglich ausprobiert habe, aber das 'git svn fetch' macht keine 're-reading'-Schritte. Ich habe die ursprüngliche Frage mit der vollen Ausgabe aktualisiert, die ich sehe. –

2

git svn reset <revision-number> funktioniert, aber Sie müssen eine Revisionsnummer angeben, die älter ist als die problematische Festschreibung, und wiederholen Sie dann git svn fetch. Nehmen wir an, der geänderte Commit ist R.100, Sie müssen git svn reset 99 dann tun git svn fetch, nur das wird das neue geänderte Festschreiben erneut holen.

Ab Ihrem Fall von 730c2ab enthält, von b89af06-93920f9 zerquetscht:

* 7b12bbc (origin/branchname) Remove dummy file 
* 730c2ab Add dummy file # But `git show 730c2ab` includes the diffs 
    between b89af06 and 93920f9 as well 
| * 93920f9 (HEAD) Uninteresting commit 
| * 91c7163 Uninteresting commit 
| * ce51022 Commit with the changed commit message 
|/ 
* b89af06 Uninteresting commit 

git-svn gelegentlich tun auf Commits, die sich geändert hat. Ich bin mir nicht sicher, was genau ist, aber gelegentlich, wenn sich die Arbeitskopie eines bestimmten Commits auf dem SVN seit dem letzten Abruf geändert hat, wird git svn die Änderungen zusammen mit dem nächsten Commit beim nächsten Abruf quetschen. Um dieses Problem zu lösen, können Sie zum vorherigen zurückgesetzt begehen, und wieder holen wieder

EDIT:

ich vorher nicht bemerkt, dass ce51022 bereits von Ihrem Hauptzweig löst. SVN verzweigt sich anders und git-svn wird nicht in der Lage sein, deine Git-Zweige auf svn zu persistieren. Dies führt auch dazu, gequetschte commit auch, wenn Sie git Svn dcommit oder git Svn holen/Rebase