web-dev-qa-db-de.com

Wie vermeide ich Konflikte im Team?

Wir sind einige Entwickler, die an demselben Projekt arbeiten, und wir verwenden git für das Projekt. Wenn zwei oder mehr von uns an derselben Datei arbeiten, erhalten wir Konflikte, die schwer zu bewältigen sind. Manchmal gehen Änderungen, die ein Entwickler vornimmt, verloren, wenn diese Konflikte auftreten.

Wie arbeiten sie mit git im Team? Was sollte der richtige Fluss sein, um Git-Konflikte zu vermeiden?

Danke im Voraus.

38
Dev01

Bevor Sie sich tief in Ihren Arbeitsablauf einarbeiten, bevor Sie einen Moment Zeit verbringen oder einen Dollar Geld für den Wiederaufbau Ihrer Kommunikationsprozesse aufwenden, stellen Sie Ihrem Team drei Fragen:

  1. Erzwingen wir Whitespace-Konventionen?
  2. Wenn wir IDEs verwenden, verwenden sie alle dieselben Formatierungs- und Schlüsselworteinstellungen? Zum Beispiel kann Eclipse automatisch Parameter abschließen .
  3. Generieren wir Text-Build-Artefakte? Beispiel: Minimieren Sie js, generieren Sie CSS-Regeln aus .sass- oder .scss-Dateien oder erstellen Sie XML-Konfigurationen im Handumdrehen. Checken wir sie ein

Nachdem ich jahrelang Konflikte erzeugt und anderen geholfen habe, sie in zentralisierten Workflows zu lösen, lege ich diese drei Dinge für die überwiegende Mehrheit unserer kollektiven Konfliktsituation bereit:

The causes of merge conflicts

Im obigen Bild wird das "!" Slice steht für legitime Zusammenführungskonflikte. Die weite Mehrheit der schrecklichen Verschmelzungen kommt von faulen Whitespace-Konventionen oder übermäßig aggressiven IDEs (oder gelegentlich zu stark refaktorischen Entwicklern). Bevor Sie etwas anderes tun, standardisieren Sie Ihre IDE - Einstellungen und die Whitespace-Konventionen. Dann müssen alle diesen Befehl in ihren lokalen Repositorys ausgeben:

# Enable the repository's stock pre-commit hook
mv .git/hooks/pre-commit.sample .git/hooks/pre-commit

Dieser Pre-Commit-Hook führt bei jeder Ausgabe von git commit eine Reihe von Prüfungen durch, einschließlich einer Version von git diff --check, einem Befehl, mit dem überprüft wird, ob die festgeschriebenen Änderungen Whitespace-Fehler verursachen. Das Festschreiben wird abgelehnt, wenn dies der Fall ist. Wenn Sie es wirklich umgehen müssen, können Sie git commit --no-verify ausgeben, aber nicht: Whitespace-Fehler sind wie die nicht explodierte Verordnung der Versionskontrolle. Es sind Mischkonflikte, die nur darauf warten.

Wenn Sie Leerzeichen bereinigen, eine Datei umgestalten möchten, um die Einrückung zu verbessern, oder eine andere Reihe von reinen Formatierungsänderungen vornehmen, tun Sie dies in isolierten Commits und weisen Sie das Team an, zunächst die in Konflikt stehenden Arbeiten zu überprüfen.

Wenn Sie Codeüberprüfungen durchführen, stellen Sie die erste Frage, die jeder Überprüfer stellt: "Wurde dieser Änderungssatz mit irgendetwas nicht berührt? Dies sollte nicht geschehen? Wenn dies der Fall ist, schlagen Sie die Überprüfung fehl. Wenn dies nicht der Fall ist, stellen Sie sicher, dass diese Änderungen ausreichend von den logischen Änderungen (d. H. In verschiedenen Commits) isoliert sind, um Ihre Historie nützlich zu machen.

Stylesheet-Sprachen, RequireJS- und js-Minifizierer verursachen auch Konflikte, wenn ihre generierten Ziele eingecheckt werden. Die durch diese Technologien erstellten Dateien sind Build-Artefakte. Sie würden kein WAR-Archiv einchecken. checken Sie keine SASS-kompilierte CSS-Datei ein. Wenn Sie der Meinung sind, dass Sie dies tun müssen, verwenden Sie eine .gitattributes-Datei , damit git sie als Binärdateien behandelt.

Wenn Sie nach all diesen Dingen immer noch Konflikte beim Zusammenführen haben, führen Sie Verbesserungen im Arbeitsablauf durch. Die Antwort von Gary Fixler ist absolut richtig: Legitime Verschmelzungskonflikte entstehen, weil Teams den Umfang ihrer Projekte nicht oder nicht gut kommunizieren können. Stellen Sie nur sicher, dass die Formatierungsregeln zuerst nicht durchgesetzt werden.

47
Christopher

Um ehrlich zu sein, erfordert der richtige Workflow eine gute Kommunikation und ein gutes Management. Teammitglieder sollten nicht oft an der gleichen Sache arbeiten und Konflikte verursachen. Dinge wie das tägliche Aufstehen und ein aufmerksamer Manager, der weiß, was jedes Mitglied des Teams vorhat - zumindest im Allgemeinen - wird in vielen Fällen viel tun, um dies einzuschränken.

Dies hängt natürlich von der genauen Art des Produkts ab, ist jedoch eher eine organisatorische als eine git-Frage. In der Tat werden Konflikte oft als "gute" Dinge angesehen, weil sie die Leute dazu bringen, von ihren Schreibtischen aufzustehen oder sich gegenseitig anzurufen, um darüber zu sprechen, warum es einen Konflikt gab und was dagegen unternommen werden sollte. Dies ist eine Chance herauszufinden, dass eine Person einen Bereich oder eine Reihe von Dateien besitzen sollte oder zumindest der Ansprechpartner für die Erörterung von Änderungen an diesem Abschnitt ist.

Abgesehen von der Erstellung eines Vorabplans gibt es keine Möglichkeit, Git-Konflikte zu vermeiden, dies wäre jedoch in jedem Versionssystem das gleiche Problem. Jedes Mal, wenn zwei Personen denselben Codeabschnitt ändern, müssen Sie herausfinden, wer gewinnt. Aus diesem Grund ist es nicht angebracht, den Versionsverwalter nach der Lösung zu fragen, sondern sich mit den Methoden und Vorgehensweisen Ihres Teams zu befassen. Zwei Autos können nicht gleichzeitig eine Kreuzung durchfahren, aber es ist extrem schwierig, Autos zu erfinden, die sich gegenseitig passieren können. Stattdessen haben wir die Kontrollsysteme für Stoppschilder und Verkehrssignale erfunden. Dies ist ein ähnliches Problem. Wir können nicht wirklich zwei Änderungen an derselben Sache vornehmen, nicht an Konflikten. Deshalb müssen wir steuern, wie wir mit den Dateien arbeiten.

Sie könnten eines der Frontends in Betracht ziehen, das das Einschließen von Git ermöglicht, aber ich stimme dem Konzept nicht wirklich zu, abgesehen von nicht zusammenfügbaren Dateitypen. Ich denke, es ist besser, einen besseren Teamworkflow zu finden und dies als Gelegenheit zu nutzen, um Dateien wirklich gut zusammenzuführen. Ich habe das getan, und jetzt, nachdem ich es monatelang getan habe, sind Konflikte für mich kein Problem.

12
Gary Fixler

Es gibt nur einen Weg, um Konflikte zu vermeiden: Lassen Sie nicht die gleiche Datei von verschiedenen Personen gleichzeitig bearbeiten. Im Wesentlichen hat jede Datei einen Eigentümer, der für alle Änderungen verantwortlich ist und der den Besitz auf einen anderen übertragen kann. Das Eigentum an einer Datei kann auf der Grundlage eines bestimmten Features/Zweiges oder des Alltags weitergegeben werden, solange das Eigentum eindeutig ist.

Wenn Sie feststellen, dass Sie nicht für jede Datei einen Besitzer angeben können, gilt Folgendes:

  • sie müssen Ihre Dateien in kleinere Dateien aufteilen, die einem Eigentümer zugewiesen werden können
  • es ist absolut erforderlich, dass GIT-Konflikte gelöst werden (alle Redakteure sitzen zusammen, um die einzelnen Konflikte zu lösen). 
  • Verwenden Sie ein gutes Multi-Merge-Tool, um die Konflikte zu visualisieren und anschließend zu lösen.
7
GoZoner

Bestellung.

Es gibt ein paar andere Dinge, die Sie tun können, die auch helfen könnten ... Es wird klarer, wenn ich sie separat poste.

Wo Sie neue Dinge einfügen, hilft Ihnen festzustellen, ob Sie Konflikte erzeugen.

Stellen Sie sich eine Liste mit Namen der Angestellten vor 

Andy, 
Oliver, 
Ivan,

Dann schließen sich Brad und Patrick an, und ihre Namen werden der Liste hinzugefügt ... Sie fügen Brad hinzu und ich füge Patrick hinzu. Wir fügen beide die Namen am Ende der Liste hinzu und verwenden dann git, um unsere Listen zusammenzuführen. Das Ergebnis ist den Benutzern von git bekannt: -

Merge branch 'Patrick' into Brad

Conflicts:
    names.txt

@@@ -1,4 -1,4 +1,8 @@@
  Andy, 
  Oliver, 
  Ivan,
  <<<<<<< HEAD
 +Brad,
  =======
+ Patrick,
  >>>>>>> Patrick

Nehmen wir an, wir hätten dasselbe getan, aber eine einfache alphabetische Reihenfolge in unsere Liste aufgenommen. Wenn wir nun die beiden Äste zusammenführen, sind die Ergebnisse etwas erfreulicher:

Andy,
Ivan,
Oliver,

Fügen Sie einen Namen selbst hinzu und führen Sie dann die Änderung der anderen Person mit git zusammen, um den anderen Namen hinzuzufügen.

Auto-merging names.txt
Merge made by the 'recursive' strategy.
 names.txt | 1 +
 1 file changed, 1 insertion(+)

Und wir bekommen

Andy,
Brad,
Ivan,
Oliver,
Patrick,

Da wir nicht wissen, wer als nächstes dem Unternehmen beitreten wird, fügen wir die Liste in zufälliger Reihenfolge hinzu, und durch Einfügen an zufälligen Orten sind Ortskonflikte in den Dateien weniger wahrscheinlich.

3
user3070485

Angehängte Blockstarts verwenden

In Software wie dieser ...

function chess() 
{
    while (!end_of_game)
    {
        make_move()

die Zeilen, die Blöcke mit Öffnungsklammern beginnen, können leicht mit anderen Zeilen in der Software verwechselt werden, die aus einzelnen Öffnungsklammern bestehen. Wenn dieselbe Software so geschrieben ist, beginnt das Anhängen des Blocks an die vorherigen Zeilen ...

function chess() {
    while (!end_of_game) {
        make_move()

was ich persönlich nicht mag, aber Git tut es Es gibt viel weniger Zeilen, die Git ähnlich sehen und sich falsch verstehen, dh Git nimmt die Bearbeitung wahrscheinlich auf die gleiche Weise wahr, die wir machen Konflikte viel einfacher zu lösen.

Und Kommentare zu Blockenden

Verwenden Sie Kommentare, um ähnlich aussehende Zeilen unterscheidbar zu machen.

Wenn Sie viel Javascript und JSON schreiben, haben Sie möglicherweise viele Zeilen, die ein bisschen so aussehen.

            }
        }
    }
)

Wenn Sie Dinge kommentieren, können sie unterscheidbar werden.

            }
        }
    }
) // end of weekdays()

und

            }
        }
    }
) // end of weekend()

sieht nicht mehr so ​​aus wie git. Dies kann dazu beitragen, Ihre Änderungen besser zu verstehen. Wenn Sie etwas hinzufügen, wie 

function a()
{
    ...
} // end of a()

git sieht das eher als eine Einheit der Veränderung und glaubt nicht, dass Sie so etwas hinzugefügt haben

}

function a()
{
    ...

kurz vor dem Ende einer anderen Funktion. Selbst wenn dies Konflikten nicht vorbeugt, wenn git Ihre Änderungen sinnvoll sieht und darstellt (d. H. Die Art und Weise, wie wir sie mental betrachten), können Sie Konflikte möglicherweise leichter lösen. Ein beschreibender Header, der die Funktionen, die von ihnen verwendeten Parameter usw. kommentiert, wird außerdem dazu beitragen, dass der Inhalt der benachbarten Funktionen nicht durcheinander gebracht wird.

2
user3070485

Informieren Sie die Kollegen, wenn Sie Ihre Änderungen vorangetrieben haben

Eine weitere Möglichkeit, den Schmerz von Konflikten zu reduzieren, besteht einfach darin, Kollegen zu informieren, wenn Sie Ihre Änderungen vorangetrieben haben. Es ermöglicht ihnen, Ihre Änderungen zu übernehmen und Konflikte dort und dort zu lösen. Konflikte sind wahrscheinlich zwischen Ihrer letzten Änderung, frisch in Ihrem Kopf und dem, woran sie arbeiten, frisch in ihrem Kopf. 

Wenn die Benutzer die Änderungen nicht aus dem Hauptzweig ziehen, bis sie eine große Entwicklung abgeschlossen haben und dann Konflikte mit den Änderungen einer Reihe von Personen in demselben Bereich haben, wird es schwieriger zu lösen sein.

Verwenden Sie ein Mergetool

 enter image description here

Eine der Aufgaben von Git ist die Versionskontrolle. Andere Programme sind auf das Zusammenführen von Dateien und das Lösen von Konflikten spezialisiert. Wenn Sie ein Mergetool für die Verwendung mit git konfigurieren, kann es automatisch viele Probleme lösen, die von git als Konflikt betrachtet werden, oder Sie sollten zumindest eine sehr gute Vermutung für Sie suchen und einfach unberührt lassen, wenn es in Ordnung aussieht oder Sie dem Werkzeug vertrauen .

So bleiben weniger echte Konflikte, für deren Lösung eine intelligente Entscheidung erforderlich ist.

Verwenden Sie kleinere Dateien

Ich füge einen neuen Controller am unteren Rand von mycontrollers.js hinzu, und Sie fügen einen neuen Controller am unteren Rand von yourcontrollers.js hinzu: kein Problem.

Wir fügen beide einen neuen Controller am Ende von allcontrollers.js: conflict hinzu.

(Beachten Sie jedoch auch den Ratschlag, die Dinge alphabetisch zu bestellen. MyNewController (), der mit M beginnt, wird möglicherweise in die Mitte einer Datei verschoben und IhrNewController (), der mit Y beginnt, könnte am Ende derselben Datei wieder ohne Konflikte gehen.)

1
user3070485

Um die Anzahl der Konflikte bei der Versionskontrolle zu reduzieren, ohne sich Gedanken darüber zu machen, wer gerade was bearbeitet, müssen Sie lediglich kleinere Änderungen vornehmen und sie schrittweise festschreiben. Teilen Sie das Problem in so kleine Stücke auf, dass Sie schnell Dateien ändern können, und legen Sie sie in den Trunk zurück. Je kurzlebiger Ihre Zweige sind, desto geringer ist die Wahrscheinlichkeit, dass Konflikte entstehen.

Selbst dann werden zwei Personen die gleiche Datei zur gleichen Zeit ohne eigenes Verschulden bearbeiten. Die offensichtliche Frage, wenn das passiert, ist:

"Wie kann ich den Konflikt mit der Lösung von Konflikten lösen?"

Die Antwort ist, dass Sie den Stamm regelmäßig ziehen und Ihren Zweig darauf abstützen müssen, und Sie werden die Konflikte so früh wie möglich bemerken, solange sie noch klein sind. An diesem Punkt sollten sich beide Entwickler zusammensetzen und in Ruhe über die beste Vorgehensweise diskutieren, während die Änderungen in ihrem Kopf neu sind.

Vergleichen Sie diesen Ansatz mit dem Versuch, Konflikte in großen, langlebigen Zweigen in Panik zu lösen, kurz vor dem Veröffentlichungsschluss, wenn sich die Entwickler schwer tun, sich an die Überlegungen zu erinnern, die hinter den vor einiger Zeit vorgenommenen Änderungen stehen.

0
Will Sheppard

Verwenden Sie UTF-8 nicht UTF-16 für Textdateien.

Viele Git-Versionen (d. H., Soweit ich weiß, alle Versionen, die ich verwendet habe) können UTF-16-Dateien als Binärdateien behandeln, da in einer typischen UTF-16-Textdatei viele Null-Bytes vorhanden sind.

Wenn Git der Meinung ist, dass eine Datei eine Binärdatei ist, wird sie wahrscheinlich auch dann als Binärdatei behandelt, wenn sie geändert wird. Dies bedeutet, dass die Versionskontrolle durch das Speichern vollständiger Versionen der Datei durchgeführt wird, anstatt die Unterschiede zwischen ihnen und die Vorteile eines Versionskontrollsystems zu verlieren. (Edit: Nein.) Ich habe dies kürzlich getestet, indem ich eine UTF-16-Datei in UTF-8 geändert habe, sie begebe, bearbeite und erneut bestätige - und die Änderungen wurden als Textänderungen behandelt, sobald BEIDE die ursprünglichen und bearbeiteten Dateien UTF-8 waren. )

Die meisten modernen Editoren erkennen die Zeichenkodierung und den Zeilenendstil einer Datei und speichern die Datei im gleichen Format. In einigen Editoren (z. B. Babelpad) können Sie auswählen, ob Sie Ihre Datei in UTF-8 oder UTF-16 und mit oder ohne Byte-Auftragskennzeichen usw. speichern möchten. 

Wenn die zur Versionskontrolle gewünschte Datei (i) im UTF-16-Format ist und (ii) in UTF-8 gleichermaßen funktionieren würde - beispielsweise als Quellprogramm für einen anständigen modernen Compiler -, ist es eine Überlegung wert, sie in zu konvertieren UTF-8.

Wenn Git der Meinung ist, dass Ihr Quelltext vor dem ersten Commit eine Binärdatei ist, schauen Sie nach, ob es sich lohnt, ihn in einem Editor zu laden und in einem anderen Format zu speichern, das Git als Text erkennt.

(Hinweis: Linux-Dateien sind in der Regel standardmäßig UTF-8. Einige Windows-Programme hatten die Angewohnheit, UTF-16 zu erstellen. Es ist also am wahrscheinlichsten, dass Windows-Benutzer das Problem haben. Beachten Sie auch, dass Sie dies vor dem eigentlichen Problem korrigieren möchten Erstes Commit der Datei, bevor Git der Meinung ist, dass es eine Binärdatei hat!)

 enter image description here

Verwenden Sie Git rerere

Aufgenommene Auflösung wiederverwenden!

https://git-scm.com/book/de/v2/Git-Toolss-Rerere

0
user3070485