2010-04-22 4 views
24

Ich habe eine Verzweigung (nennen wir es B), die eine bestimmte Datei ignoriert, die nicht in anderen Branchen (zB Zweig A) ignoriert wird. Wenn ich von Zweig B zu Zweig A und dann wieder zu B zurückwechsle, wurde die Datei gelöscht.Git löscht eine ignorierte Datei, wenn ich verzweige

Ist das normal? Ich kann irgendwie sehen, wie es passieren würde, in dem Sinne, dass Zweig B denkt, dass es nicht da ist, und Zweig A denkt, dass es so ist, also, wenn ich zurück nach B gehe, räumt es weg. Aber es ist irgendwie nervig.

Irgendwelche Vorschläge?

+0

Gibt es einen Grund, warum Sie es nicht in allen Zweigen ignorieren oder in alle Zweige aufnehmen können? – ewall

+0

Es gibt ein lustiges Problem hier: Wenn Sie es zu .gitignore in Zweig A hinzufügen und dann zu .gitignore in Zweig B hinzufügen möchten, müssen Sie Zweig B abchecken, an diesem Punkt wird die Datei gelöscht - BEVOR Sie hatten eine Chance, es zu ignorieren. Wahrscheinlich benötigen Sie ein schmutziges .gitignore in Ihrem Arbeitsverzeichnis *, das die Datei * enthält, wenn Sie die Zweige wechseln, um zu vermeiden, dass die Datei gelöscht wird. – Armand

+0

@Alison G: Dein Fall macht nicht viel Sinn. Damit dies geschehen kann, muss die Datei in Zweig A * nachverfolgt werden. Sie würden sie daher niemals in Zweig A in den Zweig gitigore aufnehmen. Die Datei wird entfernt, da sie in einem Zweig verfolgt wird und nicht existiert das andere. Der einzige Effekt, der es ignoriert, besteht darin, dass Sie von B nach A wechseln können, ohne dass Sie gewarnt werden, dass Sie eine Datei in der Arbeitshierarchie überschreiben. – Cascabel

Antwort

2

Es ist normal, obwohl ich von einem Schritt etwas überrascht bin.

Wenn Sie von B nach A wechseln, sieht git, dass die Datei aktualisiert werden muss, damit sie der Version von A entspricht. Dies geschieht stillschweigend, weil Sie sie ignoriert haben. t Angelegenheit. Es muss dies tun - die einzige Alternative ist es, den Zweig A nicht zu überprüfen. (Es würde sich weigern, wenn die Datei nicht ignoriert würde, "Untracked working tree file '' würde von merge überschrieben werden." Ich bin wirklich überrascht in diesem Fall tut das auch niemand.Jeder hat irgendeinen Einblick, ob das Feature oder Bug ist?)

Wenn Sie zurück zu, Git sieht, dass Zweig B diese Datei nicht hat, und entfernt es. Auch das muss es tun. Es hat keine Möglichkeit, deine Gedanken zu lesen und zu erkennen, dass diese ignorierte Datei, die vor einer Minute dort war, eine ist, die du zurückhaben willst - sie gibt dir einfach den Inhalt von Zweig B, der besagt, dass die Datei nicht existiert.

Wie ewall in den Kommentaren empfiehlt, wenn die Datei diese Übergänge überleben soll, muss sie von allen Zweigen verfolgt oder in allen Zweigen ignoriert werden.

4

Da die einzige praktikable Lösung ist jederzeit die Datei 'f' zu verfolgen, könnte man hinzufügen, nur in Zweig B, ein smudge/clean process mit einem gitattributes filter driver:

https://raw.github.com/adisp007/ProGit/master/figures/18333fig0702-tn.png

Wenn checkouting Zweig B:

:

  • würde der wisch Prozess ändern

    • speichert den Inhalt f in einer temporären Datei
    • den Inhalt f mit einer fbis Datei ersetzen (ein verfolgtes Datei, die zum Zweig enthalten würde B, das „B Gehalt an f“)
  • der sauberen Prozess würde:

    • speichern f Inhalt (wie in B modifiziert) in 0.123.
    • wiederherstellen f Inhalt (mit der temporären Datei) wird noch hinzufügen

Sie können f Sinn (fbis wird mit f Änderungen im Zweig B begangen) nicht begangen (in B ignoriert), in Zweig B, ein custom merge driver, der fbis schützen wird im Fall von Zusammenführungen von anderen Zweigen zu B:
der Merge-Treiber wird immer B Version behalten von fbis Inhalt, stellen Sie sicher, dass die ignorierte Datei f erhält seinen Inhalt zurück, wenn Zweig B ausgecheckt ist.

Da diese Treiber (Filter und Zusammenführen) in anderen Zweigen nicht festgeschrieben sind, wird die Datei 'f' in allen Zweigen mit allen ihren Änderungen festgeschrieben.
Im Zweig B wird sich sein Inhalt niemals ändern, und dennoch werden die "lokalen Änderungen", die an f vorgenommen wurden, immer noch wiederhergestellt, wenn B ausgecheckt ist. Wenn diese Inhaltswiederherstellung nicht erforderlich ist, müssen Sie fbis nicht verwalten.
Halten Sie einfach den Filtertreiber und Sie werden sicher sein, dass, was auch immer Sie an f in Zweig B ändern, diese Änderungen nie begangen werden, effektiv ignorieren f Inhalt.

+2

wow, @VonC das ist eine erstaunliche Antwort, vielen Dank. Ich bin mir nicht sicher, dass ich schlau genug bin, um es zu verstehen ... hängen Sie, brauchen Sie noch eine Tasse Kaffee ... –

+0

Oder für jeden Zweig haben zwei separate Arbeitsverzeichnisse und vermeiden Sie das Auschecken Problem vollständig ... ähnlich SVN Verzweigungsmodell, was ich gemacht habe. Auf unzusammenhängende Notiz eine interessante Geschichte lesen: http://blog.red-bean.com/sussman/?p=20 –

+0

@DanielSokolowski Dies ist eigentlich möglich seit Git 2.5: http://Stackoverflow.com/a/39626426/6309 und http://stackoverflow.com/a/30185564/6309 – VonC

0

Ich habe eine ähnliche Situation erlebt, und ich das tun:

Ich werde die Datei, die in der Kasse von index.php gelöscht nennen.

In Ihrem.gitignore von Zweig A und Zweig B entfernen Sie die Zeile, die Ihre index.php ignorieren, nach diesem Beglaubigung .gitignore in beiden Zweigen.

In Zweig A, erstellen Sie eine Sicherungskopie von index.php, löschen Sie diese und begehen.

in Zweig wiederherstellen A die index.php aus dem Backup zuvor die diese index.php und begehen erstellt und wieder in Ihrem .gitignore ignorieren.

In Ihrem Zweig B fügen Sie den index.php, die Datei in Ihrem .gitignore ignorieren, begehen und glücklich sein.

+0

Funktioniert nicht für mich. – blinry

1

Das Ignorieren von Dateien in git bedeutet nicht, dass sie nicht überarbeitet werden. Sie können eine Datei in git eingecheckt und verwaltet haben und sie in .gitignore ignorieren lassen.

Verwandte Themen