# GIT Workflow an konkretem Beispiel



## Marco13 (11. Jan 2012)

Hi

Der Workflow, für den GIT entwickelt wurde, scheint so sehr von meinem abzuweichen, dass ich immer wieder auf vermeintlich triviale Probleme stoße  

- Es gibt auf einem Server ein Repository mit Klassen A, B, C
- Das repo ist bei mir lokal geklont
- Ich verändere lokal die Klassen A und B
- Jemand anderes verändert bei sich lokal die Klassen B und C
- Jemand anderes Pusht die Klassen B und C auf den Server

Eigentlich etwas, womit man bei "verteilter Entwicklung" rechnen muss, oder? :bahnhof:

Wie (zum ... ) kann ich nun herausfinden, was jemand anderes in der Zwischenzeit gemacht hat? Und insbesondere: Wie kann ich mein lokales Repo auf den neuesten möglichen Stand bringen, OHNE meine (unfertigen) Änderungen zu committen? Man könnte die lokalen Änderungen auf den Stash legen, aber mal im Ernst: Das funktioniert einfach nicht! :noe: Jemand anderes hat Klasse B geändert, und im Stash liegt auch eine geänderte Klasse B - da kommt man in die Hölle, wo man nicht pullen kann, weil man nicht committed hat, nicht committen kann, weil man nicht gepullt hat, nicht poppen kann, weil man nicht gemergt hat, und nicht mergen kann, weil man nicht gemergt hat (äh.. jaaaa...!? :noe

Gibt's eine dieser typischen Befehlszeilen wie
git pull -distant/origin -magic[~42##] -rebase * ~reallyDoIt ++hard +++andEvenHarderIfNecessary
mit der man sagen kann: Aktualisiere mein Repo auf den Stand vom Server (und wenn dabei Probleme auftreten, lass' das meine Sorge sein) ?

bye


----------



## AngryDeveloper (11. Jan 2012)

Ich denke mal du arbeitest bestimmt auch mit Branches und nutzt Git nicht nur wie CVS oder SVN?

Statt git pull solltest du, um vom origin die aktuellen Änderungen zu holen, git fetch benutzen. Damit kannst du dir die neuen Änderungen angucken (git diff mit dem origin) und mit git merge selbst mergen, anstatt das alles git pull zu überlassen.
Möglichst simpel ausgedrückt, ist git pull quasi ein git fetch gefolgt von git merge in den aktuellen Branch.

Gibt relativ viel darüber. Z.B. dieser Blog Post: git: fetch and merge, don’t pull  Mark’s Blog

Das Buch über Git kann ich auch empfehlen: Pro Git - Table of Contents


----------



## schalentier (11. Jan 2012)

Marco13 hat gesagt.:


> Wie kann ich mein lokales Repo auf den neuesten möglichen Stand bringen, OHNE meine (unfertigen) Änderungen zu committen?



[c]git fetch[/c] aktualisiert dein lokales Repo. Du meinst sicherlich deine aktuelle Working Copy (dein ausgecheckter Filetree). Und diesen kannst du nicht aktualisieren, ohne deine Aenderungen zu committen. [c]git stash[/c] macht uebrigens nichts anderes als einen Commit, nur landet der eben im Stash und nicht im Repo. Und das funktioniert wunderbar. 

Wenn du und ein andrer die gleiche Datei geaendert haben, kommt es zu einem Konflikt. Git versucht den zu loesen, aber sobald da ein Problem auftritt, hoert Git auf und du musst mit dem Tool deiner Wahl den Konflikt manuell beheben ([c]git mergetool[/c]). 

Ich arbeite auch meistens mit Rebase. Hat den Vorteil, das im Grunde zuerst der Remotestand geholt wird und dann deine lokalen Commits drueber gelegt werden. Macht aber nur bei kleineren und wenigen Commits Sinn (z.B. bei Bugfixes).


----------



## Marco13 (11. Jan 2012)

Das mit dem manuellen fetchen werde ich bei Gelegenheit mal ausprobieren - klingt als könnte es das sein, was ich brauche. Vermutlich wird das auch wieder zu abstrus-widersprüchlichen Fehlermeldungen führen, und die Websuche dazu auf StackOverflow, wo Links zu Büchern gepostet werden, aber ... das "Problem" mit diesen Onlinequellen ist, dass für mich und 99% der anderen Entwickler 99% der Arbeit aus 2 Dingen besteht: 
- Gib mir den aktuellen Stand
- Füge meine Änderungen in den aktuellen Stand ein
und die Onlinequellen haben die Tendenz, seitenlang über ""coole"" Features zu schwadronieren, die mit diesen einfachen Tasks nichts zu tun haben. Mal schauen...


----------



## musiKk (11. Jan 2012)

Marco13 hat gesagt.:


> Wie kann ich mein lokales Repo auf den neuesten möglichen Stand bringen, OHNE meine (unfertigen) Änderungen zu committen? Man könnte die lokalen Änderungen auf den Stash legen, aber mal im Ernst: Das funktioniert einfach nicht!



Das verstehe ich nicht. Das mache ich dauernd so. Oder vergisst Du das [c]stash pop[/c] hinterher?



AngryDeveloper hat gesagt.:


> Das Buch über Git kann ich auch empfehlen: Pro Git - Table of Contents



Dem kann ich nur zustimmen. Man sollte imho mindestens den Anfang gelesen haben, dann kommt man auch mit manpages ganz gut weiter. Mit dem Rest kann man es dann auch wie mit der Insel halten: Nachschlagen, wenn mans braucht.


----------



## Marco13 (11. Jan 2012)

Bisher kamen beim poppen  wenn jemand anderes in der Zwischenzeit an einer ge'stash'ten Datei etwas geändert hatte immer die Meldungen im _sinnbildlich-grob-angedeuteten(!)_ Stil von
Versuch zu poppen -> Du darfst nicht poppen, du musst erst committen
Versuch zu committen -> Du darfst nicht committen, du musst erst pullen
Versuch zu pullen -> Du darfst nicht pullen, du musst erst mergen
Versuch zu mergen -> Du darfst nicht mergen, du musst erst mergen (ja...)

Der allgemeine Hinweis, nicht zu pullen, sondern zu fetchen und zu mergen hat ganz gut gepasst - zumindest habe ich jetzt eine aktualisierte Version, und meine Änderungen sind nur lokal.

<Rant>
Ansonsten sind die Referenzen im Web oft nur... bedingt hilfreich. ("Uiiii!  Das ist ja toll, was man da so alles machen kann! Aber es interessiert mich nicht - ich will nur ändern und committen"). Vielleicht bin ich auch nur "verwöhnt", weil bei mir als In-Der-Freizeit-Alleine-Entwickler der SVN-Versionsbaum eigentlich nur eine verkettete Liste ist... 
</Rant>


----------



## musiKk (11. Jan 2012)

Kann ich nicht nachvollziehen. Der Workflow


```
$ git stash
$ git pull
$ git stash pop
```

sollte in den meisten Fällen funktionieren. Wenn Du ein fetch machst, musst Du natürlich von Hand mergen (das geht im Idealfall ohne Intervention). Mit pull hatte ich bislang noch keine Probleme (der Blog-Eintrag ist mir auch schon ein paar mal begegnet, aber bislang habe ich das nicht beachtet). Wobei wir nur rebasen und nicht mergen, damit die History nicht so hässlich wird. Wenn es zwischen dem upstream und Deinem Stash einen Konflikt gibt, musst Du den natürlich auch von Hand beheben. Aber das ist in SVN ja nicht anders - zaubern kann kein SCM.



Marco13 hat gesagt.:


> Ansonsten sind die Referenzen im Web oft nur... bedingt hilfreich. ("Uiiii!  Das ist ja toll, was man da so alles machen kann! Aber es interessiert mich nicht - ich will nur ändern und committen"). Vielleicht bin ich auch nur "verwöhnt", weil bei mir als In-Der-Freizeit-Alleine-Entwickler der SVN-Versionsbaum eigentlich nur eine verkettete Liste ist...



Verwöhnt? Wohl eher verdorben. Git commits sind ebenso nur eine verkettete Liste (wobei merge commits mehr als einen parent haben). Versuche mal nicht so Rant-mäßig an die Sache ranzugehen und schaue Dir das erwähnte ProGit an. Es ist wohl schon so, dass SVN eine geringere Lernkurve hat. Bei Git ist es hilfreich, das (nicht wirklich komplizierte) Grundkonzept verstanden zu haben. Wenn Du Dich dagegen sträubst, hast Du nur Dich selbst zu beschuldigen. Dass man als Softwareentwickler eine gewisse Flexibilität mitbringen sollte, brauche ich ja sicher keinem zu erzählen.


----------



## Marco13 (11. Jan 2012)

Es funktioniert nicht, wenn im Stash eine Datei geändert wurde, die auch in dem geändert wurde, was man gepullt hat - zumindest stand ich schon mehrfach vor diesem Problem, und habe schon mehrfach keine Lösung dafür gefunden. 

Ich weiß, dass es Leute gibt, die darauf schwören Und ich "sträube" mich nicht dagegen, in dem Sinne, dass ich es nicht können wollte. Habe nur den Eindruck, dass teilweise Tendenzen zu bestehen scheinen, "Kompliziert" und "Professionell" gleichzusetzen. Wenn man an der Konsole kryptische Befehle eintippt und den "status" abfragt, wo man dann Dateinamen mit Copy&Paste in die nächste kryptische Befehlszeile einfügen kann, und zwischendurch mal irgendein VI-artiger Dateibetrachter aufgeht und man sich vorkommt wie bei Hacker Typer MUSS man doch erkennen, dass da irgendwas falsch gelaufen ist...!? Nichts gegen ein mächtiges Werkzeug, mit dem man komplizierte Dinge machen kann. Komplizierte Dinge sollten möglich sein. Aber einfache Dinge sollten einfach sein, und das brauche ich ja auch keinem Softwareentwickler zu erzählen


----------



## schalentier (12. Jan 2012)

Marco13 hat gesagt.:


> Es funktioniert nicht, wenn im Stash eine Datei geändert wurde, die auch in dem geändert wurde, was man gepullt hat - zumindest stand ich schon mehrfach vor diesem Problem, und habe schon mehrfach keine Lösung dafür gefunden.




```
> echo -e "A\nB\nC" > test.txt
> cat test.txt
A
B
C
> git init
Initialized empty Git repository in /Users/schalentier/git_test/.git/
> git add .
> git commit -m"Commit 1"
[master (root-commit) 9b02c34] Commit 1
 1 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 test.txt
> echo -e "A\nB modified\nC" > test.txt
> cat test.txt
A
B modified
C
> git stash
Saved working directory and index state WIP on master: 83350ba Commit 1
HEAD is now at 83350ba Commit 1
> cat test.txt
A
B
C
> echo -e "A\nB modified again\nC" > test.txt
> git stash pop
Cannot apply to a dirty working tree, please stage your changes
> git add .
> git commit -m'Zwischencommit'
[master f909e06] Zwischencommit
 1 files changed, 1 insertions(+), 1 deletions(-)
> git stash pop
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
> cat test.txt
A
<<<<<<< Updated upstream
B modified again
=======
B modified
>>>>>>> Stashed changes
C
> git status
# On branch master
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#	both modified:      test.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
> git mergetool
... mergen
> cat test.txt
A
B modified conflict solved
C
> git add . 
> git commit -m'Conflict geloest' 
> git status
# On branch master
nothing to commit (working directory clean)
```

Ich find das eigentlich nich wirklich kompliziert. Ein paar Befehle, die eigentlich alle sagen, welche Optionen man als naechstes hat. Auf der Console haste aber noch mehr Vorteile, du kannst z.B. kleine Scriptchen schreiben, die ein paar der Befehle zusammen fassen. Bei uns reicht ein [c]gerrit_push <remote_branch>[/c], um die Commits zum Gerrit zu schicken. Weiterhin kann man imho Dinge viel besser erklaeren auf der Console, als durch das Beschreiben, welche Buttons man wo in der IDE druecken muss. Obendrauf kommt, dass man immer ne History hat, und so auch bei Problemen nachvollziehen kann, was man eigentlich gemacht hat (oder jemand anderes ;-) ). 

Aber man sollte auch nicht unbedingt beim Einstieg in Git mit dem Stash anfangen. Den am besten erst benutzen, wenn man weis was das Reflog ist 

Das Problem an Git ist, dass es so voellig anders funktioniert als jedes mir bekannte VCS. Man faengt also immer bei 0 an. Und Vorwissen, z.B. von SVN ist eher hinderlich ;-)


----------



## TheDarkRose (12. Jan 2012)

Nicht pullen, sondern fetchen. mit 
	
	
	
	





```
git fetcht
```
 aktualisiert du deinen origin/*, also den Klon des entfernten Repos. Danach kannst du manuell per 
	
	
	
	





```
git merge
```
 den neuen Remote Branch in deinen aktuellen ausgecheckten Branch mergen.

Und zu der Bedienung. Git wurde als Kommandozeilentool geschrieben und ist jetzt überhaupt nicht schwer darüber zu bedienen. Es gibt aber genug grafische Frontends deiner Wahl für Git.


----------



## MarderFahrer (12. Jan 2012)

Nur so als Frage dazwischen geworfen, kommen wir auf TO's Beispiel zurück.

Drei Klassen A/B/C. Man ändert die Klasse B. Die Änderung ist angewiesen auf ein paar Sachen in Klasse C.

Wie stellt man mit Git als dezentrales Repo sicher, das meine Änderungen an B nicht komplett funktionslos werden, weil in der zwischenzeit jemand anderes die Klasse C komplett umgeschrieben hat?

Synct ihr euch die gesamte Codebase, macht euch (evtl. Stundenlang) die Arbeit mit Klasse B und bevor Ihr committed, synct Ihr nochmal und hofft und betet, dass niemand in der zwischenzeit etwas an C geändert hat, was euren Code torpediert?

Bei einem zentralen Repo kann man durch locken einzelner Dateien genau sicherstellen, das niemand in der Zwischenzeit etwas damit anstellt, was sich negativ auf eure Arbeit auswirken könnte.


----------



## musiKk (12. Jan 2012)

MarderFahrer hat gesagt.:


> Drei Klassen A/B/C. Man ändert die Klasse B. Die Änderung ist angewiesen auf ein paar Sachen in Klasse C.
> 
> Wie stellt man mit Git als dezentrales Repo sicher, das meine Änderungen an B nicht komplett funktionslos werden, weil in der zwischenzeit jemand anderes die Klasse C komplett umgeschrieben hat?



Naja, das ist doch aber in anderen Systemen nicht anders. Wenn jemand eine Datei so umschreibt, dass kein Byte mehr auf dem anderen liegt, zieht das immer Nachteile für andere nach sich, die ihre Arbeit auf dem ursprünglichen Stand basieren.



> Synct ihr euch die gesamte Codebase, macht euch (evtl. Stundenlang) die Arbeit mit Klasse B und bevor Ihr committed, synct Ihr nochmal und hofft und betet, dass niemand in der zwischenzeit etwas an C geändert hat, was euren Code torpediert?



Das ist auch so eine Sache, die offenbar einigen Probleme bereitet. Ein commit kann nie fehlschlagen. Es kann erst Probleme geben, wenn man auf einen remote pushen will.

Wenn man auf einen remote branch pushen will, muss sicher gestellt sein, dass die lokale Kopie, an der man Änderungen vorgenommen hat, gemerged oder rebased wurde, sonst verweigert der remote die Annahme. Dazu holt man sich die Änderungen rein, führt den merge/rebase durch und pusht dann.

Davon abgesehen klingen die Beispiele immer so, als seien Konflikte an der Tagesordnung. Wenn permanent mehrere Entwickler so an den gleichen Klassen arbeiten, dass Konflikte auftreten, läuft imho anderswo schon etwas falsch. Ich behaupte mal, dass man in so einem Fall mit jedem SCM auf ständige merges treffen wird.



> Bei einem zentralen Repo kann man durch locken einzelner Dateien genau sicherstellen, das niemand in der Zwischenzeit etwas damit anstellt, was sich negativ auf eure Arbeit auswirken könnte.



Ok, locking gibt es meines Wissens nicht so (auch wenn gitolite dafür wohl Unterstützung hat). Dazu kann ich aber wenig sagen, das habe ich schon in SVN nie benutzt.


----------



## Marco13 (12. Jan 2012)

@schalentier: Natürlich "geht" es - wäre ja schlimm, wenn nicht  (Jetzt mal unabhängig davon, was jemand über den geposteten Code denkt, der sich schon an die netten Roten und Grünen Symbolchen im Explorer von TortoiseSVN gewöhnt hat  ). Das "Problem" (bzw. was mich daran stört) ist, dass ich nicht eine History haben will, die von Log-Messages durchsetzt ist, die alle "Zwischencommit" heißen, und ich Code mit Zeilen wie
new Exception("DEBUG: WTF is this method called?).printStackTrace();
u.ä. eben nicht einchecken will. Für mich ist das Repostory immer noch etwas, was "so sauber wie möglich" sein sollte. (Und BITTE nicht darauf hinweisen, dass man solche Commits nachher auch wieder ("irgendwie") löschen kann... )

@TheDarkRose: Es gibt frontends - allen voran eGit, natürlich. Aber wenn man sich mal das Popup-Menü ansieht: Push, Pull, Push from upstream, Commit, Rebase, alles in verschiedenen flavors... Wenn man nicht weiß, was man in der Konsole eintippen müßte, hilft einem eine "blind in ein GUI durchgeroutete Konsole" auch nur bedingt weiter, von daher sollte man auch an der Konsole bescheid wissen... (Und... sowas wie stashing unterstützt eGit eben schonmal nicht...)

@musiKk: Im konkreten Beispiel geht es bei diesen Konlikten nicht mal um Klassen, sondern um manifest/plugin/product-Dateien einer RCP-Anwendung, da sind konkurrierende Änderungen schwieriger zu vermeiden als bei Klassen (und natürlich sollten konkurrierende Änderungen an Klassen eher selten sein). 

Wie gesagt, mit dem 'fetch' scheint es zu passen... mal schauen, wie es damit so läuft...


----------



## musiKk (12. Jan 2012)

Marco13 hat gesagt.:


> Für mich ist das Repostory immer noch etwas, was "so sauber wie möglich" sein sollte. (Und BITTE nicht darauf hinweisen, dass man solche Commits nachher auch wieder ("irgendwie") löschen kann... )



Klar, man kann alles löschen, aber wenn es einmal gepushed wurde, ist davon abzuraten. Eine mögliche Alternative wäre, einen dev-branch zu eröffnen und stabile Zustände in den master- oder einen stable-branch zu mergen. Auch mit Git ist man nicht an einen speziellen Workflow gebunden. Im Gegenteil, man kann auch einen zentralisierten Ansatz verfolgen. In ProGit sind ein paar vorgestellt.



> Wie gesagt, mit dem 'fetch' scheint es zu passen... mal schauen, wie es damit so läuft...



Das mag einiges klarer werden lassen, aber die Menge der nötigen Arbeit sollte sich dadurch nicht ändern. Wie immer: Wenn Dir das hilft, dann nutze es natürlich.


----------



## schalentier (12. Jan 2012)

Marco13 hat gesagt.:


> @schalentier: Natürlich "geht" es - wäre ja schlimm, wenn nicht  (Jetzt mal unabhängig davon, was jemand über den geposteten Code denkt, der sich schon an die netten Roten und Grünen Symbolchen im Explorer von TortoiseSVN gewöhnt hat  ). Das "Problem" (bzw. was mich daran stört) ist, dass ich nicht eine History haben will, die von Log-Messages durchsetzt ist, die alle "Zwischencommit" heißen, und ich Code mit Zeilen wie
> new Exception("DEBUG: WTF is this method called?).printStackTrace();
> u.ä. eben nicht einchecken will. Für mich ist das Repostory immer noch etwas, was "so sauber wie möglich" sein sollte. (Und BITTE nicht darauf hinweisen, dass man solche Commits nachher auch wieder ("irgendwie") löschen kann... )



Aehm, sorry aber so funktioniert das nicht. Entweder du willst Git einsetzen und lebst dann damit, das man (lokal) committen MUSS, bevor man sich Aenderungen vom Remote holt - oder halt nicht und nimmst weiter SVN.

Du kannst doch nicht erwarten, dass du nur die Vorteile und schoenen Features von Git benutzen kannst, ohne dass du Git benutzen musst. Das geht einfach nicht. 

Und auch wenn du explizit schreibst, dass du den Hinweis nicht hoeren willst: Der normale Git Workflow IST nunmal so, dass man oft (sehr oft) lokal committet (und damit ein "dreckiges" (lokales) Repo hat), aber bevor man ein Feature (oder Bugfix oder sonstwas) zum Remote pushen will, die Commits dazu sinnvollerweise zusammenfasst. Wenn du das nicht willst und du auch nicht zum Umdenken bereit bist, dann lass es bitte (und bleib bei SVN, das ist auch nicht schlecht, nur kann man halt keine Branches mergen)!

PS: Das Zusammenfassen der vier letzten Commits geht so: [c]git reset --soft HEAD~4[/c] + Commit

Achso, von eGit wuerde ich die Finger lassen. Imho ist das einfach ein riesiger Bug und hat NICHTS mit Git zu tun. Git ist (jedenfalls derzeit) nur sinnvoll von der Console aus bedienbar. Wer damit nicht klarkommt oder will, ignoriert einfach Git und gut ist


----------



## TheDarkRose (12. Jan 2012)

Marco13 hat gesagt.:


> @schalentier: Natürlich "geht" es - wäre ja schlimm, wenn nicht  (Jetzt mal unabhängig davon, was jemand über den geposteten Code denkt, der sich schon an die netten Roten und Grünen Symbolchen im Explorer von TortoiseSVN gewöhnt hat  ). Das "Problem" (bzw. was mich daran stört) ist, dass ich nicht eine History haben will, die von Log-Messages durchsetzt ist, die alle "Zwischencommit" heißen, und ich Code mit Zeilen wie
> new Exception("DEBUG: WTF is this method called?).printStackTrace();
> u.ä. eben nicht einchecken will. Für mich ist das Repostory immer noch etwas, was "so sauber wie möglich" sein sollte. (Und BITTE nicht darauf hinweisen, dass man solche Commits nachher auch wieder ("irgendwie") löschen kann... )



Branching, men Jung. Erstell dir einfach einen neuen Branch, dort kannst du soviele zwischen Commits machen wie du lustig bist. Wenn es dann zu deinem eigentlichen Commit kommen würde, fetch du dir zuerst deinen origin, danach merge'st du veränderten Code in deinen Branch. Zu guter Letzt machst du einen Rebase von deinem "Zwischencommit"-Branch in deinen eigentlichen Entwicklungsbranch. Und schwups, gibt es die Zwischencommits nicht mehr und im zentralen Repo sowieso erst nicht.

Branchen ist des Git's tägliches Tool


----------



## AngryDeveloper (12. Jan 2012)

Wegen "Großer Log History".
Ich mach in meinem development Branch für ein Fix, Feature oder whatever immer sehr viele und kleine Commits. Und das ist auch kein Problem und (finde ich) auch richtig so. Das in *meinem *Branch so viele Commits und damit Logs in der History sind ist mir ganz egal, aber in meinem Hauptbranch, mit dem ich dann auch zum Remote pushen möchte, sollen natürlich nicht lauter überflüssige Commits + Log History sein.

Dafür bietet git dann z.B. auch ein interaktives rebase an. 
Damit kannst du mehrere Commits zusammenfassen etc.
Hattest du z.B. davor 5 Commits mit einzelnen Log Einträgen (add bla, add blubb, add x, ...), hast du dann nur ein Commit mit Log (added bla, blubb, x, ...)
Beim interaktiven rebase kannst du selbst bestimmen wie einzelne Commits gehandhabt werden:
Siehe: Git Interactive Rebase und/oder Git Book - Interactive Rebasing


Aber gut, dass du mit fetch schon mal den ersten Erfolg hattest. 

Edit:
Bin von eGit auch nicht sonderlich begeistert. Die Git Integration von IntelliJ gefällt mir da etwas besser, aber am besten fährt man bei Git einfach mit der Konsole.


----------



## musiKk (12. Jan 2012)

schalentier hat gesagt.:


> Aehm, sorry aber so funktioniert das nicht. Entweder du willst Git einsetzen und lebst dann damit, das man (lokal) committen MUSS, bevor man sich Aenderungen vom Remote holt - oder halt nicht und nimmst weiter SVN.



Oder man stasht, wie schon erwähnt. Entgegen Deines älteren Posts bin ich schon der Meinung, dass man den auch sehr früh sinnvoll nutzen kann. Ich benutze den stash immer nur kurz, wenn ich einen sauberen working tree benötige (meist fürs rebase).

Darüber kann man sich sicher streiten (hast Du vielleicht ein Beispiel oder einen Blog-Post, der mögliche Probleme aufzeigt?). Ansonsten full ack.



TheDarkRose hat gesagt.:


> Branchen ist des Git's tägliches Tool



Absolut. Und genau das ist leider das Problem für die vielen SVN-Nutzer. Wenn man sich nicht von der Vorstellung lösen kann, dass ein Branch ein einfaches und praktisches Konzept und keine riesige Prozedur ist, hat man mit Git viel mehr Probleme als nötig.


----------



## Marco13 (12. Jan 2012)

schalentier hat gesagt.:


> Entweder du willst Git einsetzen und lebst dann damit, das man (lokal) committen MUSS, bevor man sich Aenderungen vom Remote holt - oder halt nicht und nimmst weiter SVN.



Offenbar MUSS man es ja nicht - das war ja genau das, worum es ursprünglich ging  

Dass man am besten für jede Zeile, die man tippt, branchen sollte, hatte ich schon ein paar mal gelesen, aber es noch nicht "gelebt" - nicht zuletzt, weil ich es mir schwer vorstelle, da global Konsitenz sicherzustellen und den Überblick zu behalten (und für sowas ist die Konsole eben schlecht. Punkt.). Aber vermutlich muss man "nur" ein paar (mher) use-cases an einem Test-Repo durchspielen, um die "Scheu" davor zu verlieren


----------



## TheDarkRose (12. Jan 2012)

Marco13 hat gesagt.:


> Offenbar MUSS man es ja nicht - das war ja genau das, worum es ursprünglich ging



Doch, denn du hast dein lokales Repo und hier MUSST du commiten. Ein zentrales Repo zu haben ist kein muss.



Marco13 hat gesagt.:


> Dass man am besten für jede Zeile, die man tippt, branchen sollte, hatte ich schon ein paar mal gelesen, aber es noch nicht "gelebt" - nicht zuletzt, weil ich es mir schwer vorstelle, da global Konsitenz sicherzustellen und den Überblick zu behalten (und für sowas ist die Konsole eben schlecht. Punkt.). Aber vermutlich muss man "nur" ein paar (mher) use-cases an einem Test-Repo durchspielen, um die "Scheu" davor zu verlieren



nicht für jede Zeile, aber einfach Entwicklungsspezifisch. Pro Bugfix, pro zu imlementierenden Feature, etc. Branching ist bei Git so schön einfach. und auf der konsole auch nicht schwer. 
	
	
	
	





```
git branch <branchname>
```
, 
	
	
	
	





```
git checkout <branchname>
```
 oder kurz 
	
	
	
	





```
git checkout -b <branchname>
```
. Wieso sollte man den Überblick verlieren? 
	
	
	
	





```
git branch
```
 zeigt dir die übersicht aller branches an. Wenn man dann noch gewisse Prefixen für den Branchnamen verwendet (feature-*, issue-*, fix-*, ....) dann weiß man auch, was man da gerade hat. Im zentralen Repo sollte eh nur der master Branch und vielleicht ein, zwei andere Branches vorhanden sein. Und wenn man z.b. ein Feature, Bugfix fertig hat, wird dieser (nach fetchen und mergen des origin) in den master rebased oder merged und dann der master ins zentrale Repo gepusht und der entwicklungsspezifische branch per 
	
	
	
	





```
git branch -d <branchname>
```
 gelöscht.


----------



## schalentier (12. Jan 2012)

musiKk hat gesagt.:


> Oder man stasht, wie schon erwähnt. Entgegen Deines älteren Posts bin ich schon der Meinung, dass man den auch sehr früh sinnvoll nutzen kann. Ich benutze den stash immer nur kurz, wenn ich einen sauberen working tree benötige (meist fürs rebase).



Benutzen kann man den schon (sind ja nur zwei Befehle), aber sobald es ein beliebiges Problem gibt, ist man halt aufgeschmissen. Ich war auch schon in einer aehnlichen Situation wie Marco13, ganz am Anfang meiner Git Erfahrung. 

[c]git stash[/c] macht alle deine Aenderungen rueckgaengig, das fand ich voellig verwirrend. Dann hat der pop nicht funktioniert (warum auch immer) und ploetzlich waren meine Aenderungen halt weg... Wenn man dann nicht verstanden hat, dass beim Git alles ein Commit ist und man quasi diese Commits beliebig umsortieren, cherry-picken, was-auch-immer kann und niemand da ist, der einem hilft, ist man einfach mal ziemlich verloren. Btw, die Loesung damals waere trivial gewesen, weil die Stash-Commits im Reflog landen und von dort auch wieder hergeholt werden koennen. Weiss man das aber nicht, is der Commit weg.


----------



## musiKk (12. Jan 2012)

Marco13 hat gesagt.:


> weil ich es mir schwer vorstelle, da global Konsitenz sicherzustellen und den Überblick zu behalten (und für sowas ist die Konsole eben schlecht. Punkt.).



Ok, Du kannst es Dir nicht vorstellen, das kann ich nachvollziehen. Aber der Schluss ist deshalb nicht richtig. Punkt. (See what I did there?)



> Aber vermutlich muss man "nur" ein paar (mher) use-cases an einem Test-Repo durchspielen, um die "Scheu" davor zu verlieren



Das ist keine schlechte Idee. Wenn ich mir mal nicht vorstellen kann, wie sich ein Befehl in einem bestimmten Fall verhält, mache ich halt in /tmp fix ein Repo auf und probiere es aus. Das dauert keine fünf Minuten.



schalentier hat gesagt.:


> Benutzen kann man den schon (sind ja nur zwei Befehle), aber sobald es ein beliebiges Problem gibt, ist man halt aufgeschmissen. Ich war auch schon in einer aehnlichen Situation wie Marco13, ganz am Anfang meiner Git Erfahrung.



Verstehe. Ich habe um mich ein paar Wizards; wenn mal ein Problem auftritt, ist meist jemand da, der weiter weiß. Es ist generell nicht schlecht, wenn man jemanden greifbar hat, der sich auskennt.

Ich bleibe aber dennoch dabei: Einmal Kapitel 2 aus ProGit und man hat das wichtigste drin. Dann Kapitel 3 zum Branchen und den Rest nur bei Interesse oder Bedarf. Das dauert zwei Stunden plus Probieren.


----------



## Marco13 (12. Jan 2012)

musiKk hat gesagt.:


> Ok, Du kannst es Dir nicht vorstellen, das kann ich nachvollziehen. Aber der Schluss ist deshalb nicht richtig. Punkt. (See what I did there?)



Nun, man braucht jetzt nicht über Details und subjektives zu streiten, aber vielleicht war das mißverständlich: Ich meinte, dass eine normale Explorer-Ansicht mit präattentiv wahrnehmbaren Roten/Grünen Symbolen wie bei TurtoiseSVN, oder auch eine "Graph-ische" Darstellung der Branches wie schon bei GIT-Gui übersichtlicher ist, als eine Konsole, auf der man sich durch zig Seiten durch hashcodes identifizierte commits oder eine VI-Ansicht vom diff-format-textdaten scrollen darf...


----------



## TheDarkRose (12. Jan 2012)

1. Es gibt TortoiseGIT für die explorer ansicht
2. ich schau mir auch gern die commithystory mit grafischen frontends an. nur git add/commit/push/fetch/merge/branch bediene ich auf der konsole, da ich hier die komplette kontrolle habe, was ich mache. Bei Gui's (bestes negativ Beispiel eGit) weiß man nie, was die jetzt bei einer Repoaktualisierung so richtig machen.
3. bist du bei merge konflikten nicht auf den vi/nano/whatever angewiesen, sondern kannst diese Konflikte auch mit der IDE auflösen.


----------



## schalentier (12. Jan 2012)

[c]git log --graph[/c] zeigt das Log inkl. Merges/Rebases graphisch an. So ziemlich genauso wie gitk oder TortoiseGit. Nur ca. hunderttausend Mal schneller :-D

[c]git mergetool[/c] bietet dir eine Auswahl aller installierter Mergetools an und oeffnet den Konflikt dann halt damit. 

IntelliJ geht auch einen recht interessanten Weg, denn dort werden die herkoemmlichen Views fuer VCS benutzt und man kann nur einige Sachen direkt in der IDE machen (Changed Files, Commit, Log, Annotate, Revert und sowas). Alles andre aus bereits mehrfach genannten Gruenden lieber auf der Console.

Ich denke, wer sich nicht auf die Console einlassen mag, der sollte die Finger von Git lassen und - wenn er denn mit SVN unzufrieden ist - mal Mercurial & Co anschauen (und dann am besten hier berichten :-D).


----------

