2012-05-11 5 views
11

Ich verstehe eindeutig Git überhaupt nicht. Das ist was ich bekomme:Git Staging und Commit zwischen mehreren Zweigen

git branch (outputs that I'm on master) 
git checkout -b foo 
echo "next line" >> file (file is an existing file) 
git add file (stages) 
git checkout master 
git status (shows that file has "next line" and is staged!!) 
git commit (commits the changes that were staged on branch foo!!) 
git checkout foo 

Hier ist der Kicker. foo zeigt nun keine Änderungen mehr an der Datei im Arbeitsverzeichnis OR staged.

So sieht aus wie - alle Änderungen, die Sie vornehmen, einschließlich Ändern von Dateien und Staging, passieren alle Zweige. Wenn Sie COMMIT für eine bestimmte Verzweigung ausführen, werden diese Änderungen in allen anderen Verzweigungen mit Ausnahme der für Sie festgeschriebenen Verzweigung verworfen.

Ist das tatsächlich was ist los? Kann mir jemand das sinnvoll machen? Es hört sich nach völlig verrücktem Verhalten an und klar, ich bekomme nicht die Designidee, die das zu einer vernünftigen Sache macht.

Edit für explizites Beispiel:

$ mkdir element 
$ cd element 
$ git init 
Initialized empty Git repository in /home/dan/element/.git/ 
$ echo "one" >> one 
$ git add one 
$ git commit -m msg 
[master (root-commit) 36dc8b0] msg 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 one 
$ git checkout -b fire 
Switched to a new branch 'fire' 
$ echo "next line" >> one 
$ git checkout master 
M  one 
Switched to branch 'master' 
$ cat one 
one 
next line 
$ 

Welche offensichtlich diese Pro Buch aus dem git widerspricht:

This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.

+2

Kann meine Antwort helfen, Dinge zu klären? Ich denke, es ist älter als deine Bearbeitung, aber ich bin mir nicht ganz sicher. – larsks

Antwort

9

Es spielt keine Rolle, welche Zweig Sie hinzufügen sind, wenn Sie eine Datei, nur wenn Sie commit es. Also wenn Sie das tun:

git add file 
git checkout master 
git commit 

Sie haben die Datei an den Master-Zweig übergeben.

Hier ist ein komplettes Beispiel mit Ausgabe. Wir beginnen mit einem neuen Repository:

$ git init 
Initialized empty Git repository in /home/lars/tmp/so/repo/.git/ 

An diesem Punkt sind wir auf dem master Zweig und wir haben noch keine Dateien hinzugefügt. Lassen Sie uns eine Datei hinzufügen:

$ date > file1 
$ cat file1 
Fri May 11 13:05:59 EDT 2012 
$ git add file1 
$ git commit -m 'added a file' 
[master (root-commit) b0764b9] added a file 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 file1 

Große, haben wir jetzt einen Zweig (master) mit einem begehen. Lassen Sie uns den neuen Zweig erstellen:

$ git checkout -b foo 
Switched to a new branch 'foo' 
$ git branch 
* foo 
    master 
$ ls 
file1 

Jetzt werden wir eine Linie zu file1 hinzufügen.

$ date >> file1 
$ git status 
# On branch foo 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: file1 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Dies zeigt, dass die Datei geändert, aber noch nicht bereitgestellt wurde. Lassen Sie uns die Datei Bühne und begehen es:

$ git add file1 
$ git commit -m 'made a change' 
[foo 761bed9] made a change 
1 files changed, 1 insertions(+), 0 deletions(-) 

und starten git status:

$ git status 
# On branch foo 
nothing to commit (working directory clean) 

An diesem Punkt sieht die Datei dies wie:

Fri May 11 13:05:59 EDT 2012 
Fri May 11 13:07:36 EDT 2012 

Wenn wir wechseln zu der master Zweig, sehen wir die frühere Version der Datei ohne die zweite Zeile:

$ git checkout master 
Switched to branch 'master' 
$ cat file1 
Fri May 11 13:05:59 EDT 2012 

Änderungen an einer Datei sind auf den Zweig beschränkt, für den sie festgeschrieben wurden.

In Ihrem aktualisierte Beispiel dieser ...

$ git checkout master 

... da keinen Fehler erzeugen, um die Version von 'Eins' an dieser Stelle sowohl master und fire ist identisch. Die Änderungen im Arbeitsverzeichnis würden für beide Versionen gleichermaßen gelten.

+1

Ja - wenn du an einer Verzweigung atomar bezüglich commits arbeitest funktioniert alles wie in diesem Beispiel und es ergibt für mich Sinn. Wenn Sie modifizieren und möglicherweise ohne Commit und ohne Verzweigungen schalten, dann wechseln Sie in diesen komischen Loopy-Zustand, der in meinem ersten Post passiert ist. Ist die Moral einfach, niemals zu wechseln, ohne zu begehen? Allerdings: wenn ich das in die andere Richtung mache und an Master arbeite und auf Zweigfeuer umschalte, gibt es mir einen Fehler: 'Fehler: Sie haben lokale Änderungen an 'eins'; kann Zweige nicht wechseln. Weiß nicht, warum ich diesen Fehler nicht bekam, der die andere Richtung bearbeitet. – djechlin

+1

Wurde die Datei tatsächlich vor dem Ausführen von 'git add' verfolgt? Können Sie Ihre Frage mithilfe eines Beispielrepositorys, in dem die tatsächlichen Befehle und Ausgaben angezeigt werden, neu übersetzen? Im Allgemeinen ist es üblich, dass Sie Ihre Änderungen vor dem Wechseln der Zweige entweder festschreiben oder [stash] (http://git-scm.com/book/en/Git-Tools-Stashing). – larsks

+1

Bearbeitete Frage, um den vollständigen Dialog statt nur die Befehle anzuzeigen. Ich werde in den Vorrat schauen - es scheint, ich verstehe nicht, wie "flache" Zweige wirklich in git sind. Ich verstehe nicht, warum ich mich trotzdem schmutzig machen lasse. – djechlin

2

Der Staging-Bereich aka Index ist für alle Zweige gleich, was Ihre Beobachtung erklärt