Ich benutze Perforce seit einigen Jahren. Ich würde gerne zur Verwendung von Git für meinen persönlichen Code wechseln, aber alle Git-Tutorials, die ich gesehen habe, gehen entweder davon aus, dass Sie eine vollständige Quellcodeverwaltung n00b sind (was sie unglaublich langweilig macht) oder dass Sie es gewohnt sind svn (was ich nicht bin).
Ich kenne p4 und verstehe auch die Idee hinter einem verteilten Versionsverwaltungssystem (also brauche ich kein Verkaufsgespräch, danke). Was ich möchte, ist eine Übersetzungstabelle vom Befehl p4 in äquivalente Git-Befehle sowie die Befehle "Ich kann nicht ohne leben", die kein p4-Äquivalent haben.
Da ich vermute, dass jeder p4-Benutzer eine andere Teilmenge von p4 verwendet, sind hier einige der Dinge, die ich regelmäßig in p4 mache, die ich in git tun möchte, die aus den von mir betrachteten Dokumenten nicht sofort ersichtlich sind ::
- Erstellen Sie mehrere ausstehende Änderungslisten in einem einzelnen Client. (
p4 change
) - Bearbeiten Sie eine ausstehende Änderungsliste. (auch
p4 change
) - siehe eine Liste aller meiner ausstehenden Änderungslisten (
p4 changes -s pending
) - Liste aller geänderten Dateien in meinem Client (
p4 opened
) oder in einer ausstehenden Änderungsliste (p4 describe
) - siehe einen Unterschied einer ausstehenden Änderungsliste (ich verwende dafür ein Wrapper-Skript, das
p4 diff
und verwendetp4 describe
) - Sehen Sie für eine bestimmte Datei, welche übermittelten Änderungslisten welche Zeilen beeinflusst haben (
p4 annotate
) - Für eine bestimmte Datei finden Sie eine Liste der Beschreibungen der Änderungslisten, die die Datei betroffen haben (
p4 log
) - eine ausstehende Änderungsliste einreichen (
p4 submit -c
) - eine ausstehende Änderungsliste abbrechen (
p4 revert
)
Viele davon drehen sich um "Änderungslisten". "Änderungsliste" ist die p4-Terminologie. Was ist der git-äquivalente Begriff?
Es hört sich so an, als ob Zweige das sein könnten, was Git-Benutzer anstelle dessen verwenden, was p4 Änderungslisten nennt. Ein bisschen verwirrend, da p4 auch so etwas wie einen Zweig hat, obwohl es sich nur um vage verwandte Konzepte zu handeln scheint. (Obwohl ich immer dachte, dass das Konzept von p4 für einen Zweig ziemlich seltsam ist, unterscheidet es sich noch einmal vom klassischen RCS-Konzept eines Zweigs.)
Wie auch immer ... Ich bin mir nicht sicher, wie ich das erreichen soll, was ich normalerweise in p4-Änderungslisten mit Git-Zweigen mache. In p4 kann ich so etwas machen:
$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.
Zu diesem Zeitpunkt habe ich eine Änderungsliste, die a.txt enthält. Ich kann die Beschreibung bearbeiten und weiterarbeiten, ohne die Änderungsliste einzureichen. Wenn sich herausstellt, dass ich einige Änderungen an anderen Dateien vornehmen muss, z. B. einen Bugfix in einer anderen Codeebene, kann ich dies auf demselben Client tun:
$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.
Jetzt habe ich zwei separate Änderungslisten im selben Client. Ich kann gleichzeitig daran arbeiten und muss nichts tun, um zwischen ihnen zu "wechseln". Wenn es Zeit für ein Commit ist, kann ich sie separat einreichen:
$ p4 submit -c 12346 # this will submit the changes to z.txt
$ p4 submit -c 12345 # this will submit the changes to a.txt
Ich kann nicht herausfinden, wie ich das in Git replizieren kann. Aus meinen Experimenten geht nicht hervor, dass dies git add
mit dem aktuellen Zweig verbunden ist. Soweit ich das beurteilen kann, werden beim git commit
Festschreiben aller Dateien, die ich erstellt habe, git add
unabhängig davon, in welchem Zweig ich mich zu diesem Zeitpunkt befand:
$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt w.txt z.txt
$ git add -A .
$ git commit
Initial commit.
3 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 a.txt
create mode 100644 w.txt
create mode 100644 z.txt
$ vi a.txt z.txt
2 files to edit
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
# modified: z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git add a.txt
$ git checkout master
M a.txt
M z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M a.txt
M z.txt
Switched to branch 'zebra'
$ git add z.txt
$ git status
# On branch zebra
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
#
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
In diesem Beispiel scheinen die Erdferkel- und Zebrazweige genau die gleichen Änderungen zu enthalten, und basierend auf der Ausgabe git status
scheint es, dass das Festschreiben in beiden den gleichen Effekt hat. Mache ich etwas falsch?
Antworten:
Ich habe nicht viel perforce verwendet, daher ist dies möglicherweise keine 1: 1-Übersetzung. Andererseits haben verteilte Versionsverwaltungssysteme wie git und mercurial sowieso einen anderen Workflow, so dass es wirklich keine 1: 1-Übersetzung gibt (und es auch nicht geben sollte). Wie auch immer, hier geht's:
Erstellen Sie mehrere ausstehende Änderungslisten -> Verwenden Sie stattdessen Zweige. In Git-Zweigen sind die Zweige leicht und schnell, die Erstellung dauert weniger als eine Sekunde und die Zusammenführung normalerweise weniger als zwei Sekunden. Haben Sie keine Angst davor, sich oft zu verzweigen und neu zu gründen.
Oder machen Sie alles in einer Zeile:
Eine Liste aller ausstehenden Änderungslisten anzeigen -> Da das Äquivalent mehrerer ausstehender Änderungslisten mehrere Zweige sind, sehen Sie sich nur die Zweige an:
Wenn Sie auch entfernte Zweige anzeigen möchten:
Es wird empfohlen, einen Zweig nach einer erfolgreichen Zusammenführung sofort zu löschen, damit Sie nicht nachverfolgen müssen, welcher Zweig zum Zusammenführen ansteht und welcher bereits zusammengeführt wurde.
Alle geänderten Dateien auflisten -> Für eine einzelne ausstehende "Änderungsliste" in einem bestimmten Zweig hat git ein Konzept des Index oder Caches. Um eine Änderung zu übernehmen, müssen Sie zuerst Dateien zu diesem Index hinzufügen. Auf diese Weise können Sie manuell auswählen, welche Dateigruppe eine einzelne Änderung darstellt, oder irrelevante Dateien ignorieren. Um den Status zu sehen, welche Dateien zu diesem Index hinzugefügt wurden oder nicht, gehen Sie einfach wie folgt vor:
Siehe einen Unterschied einer ausstehenden Änderungsliste -> Dies besteht aus zwei Teilen. Zuerst sehen Sie einen Unterschied zwischen dem Arbeitsverzeichnis und dem Index:
Aber wenn Sie den Unterschied zwischen dem, was Sie gerade eingeben, und dem letzten Commit wissen möchten, dann fragen Sie wirklich nach einem Unterschied zwischen dem Arbeitsverzeichnis + Index und dem HEAD:
Sehen Sie für eine bestimmte Datei, welche übermittelten Änderungslisten welche Zeilen beeinflusst haben -> Dies ist einfach:
oder noch besser, wenn Sie sich in einer Fensterumgebung befinden:
Git GUI braucht länger, um die Datei zu analysieren (sie wurde in tcl anstelle von C geschrieben), aber es hat viele nette Funktionen, einschließlich der Möglichkeit, durch Klicken auf eine Commit-ID eine Zeitreise in die Vergangenheit zu unternehmen. Ich wünschte nur, sie würden eine Funktion für "Zeitreisen" in die Zukunft implementieren, damit ich herausfinden kann, wie ein bestimmter Fehler endlich behoben wird ;-)
Für eine bestimmte Datei finden Sie eine Liste der Beschreibungen der Änderungslisten, die die Datei betroffen haben -> auch einfach:
Aber Git Log ist ein viel mächtigeres Werkzeug als nur dieses. Tatsächlich huckepack die meisten meiner persönlichen Skripte aus dem Git-Protokoll, um das Repository zu lesen. Lesen Sie die Manpage.
Senden Sie eine ausstehende Änderungsliste -> Auch einfach:
In meiner Antwort auf eine vorherige Frage finden Sie meinen typischen Git-Workflow: Git lernen. Ich muss wissen, ob ich auf dem richtigen Weg bin
Wenn Sie dem von mir beschriebenen Workflow folgen, sind Tools wie gitk viel wertvoller, da Sie damit Gruppen von Änderungen klar erkennen können.
Zusätzliche Antwort:
Git ist sehr flexibel und es gibt verschiedene Möglichkeiten, das zu tun, was Sie beschreiben. Denken Sie daran, für jede Funktion, an der Sie arbeiten, immer einen neuen Zweig zu starten. Dies bedeutet, dass der Hauptzweig nicht berührt wird, sodass Sie jederzeit zu ihm zurückkehren können, um Fehler zu beheben. Wenn man in Git arbeitet, sollte man fast immer beginnen mit:
Jetzt können Sie die Datei a.txt bearbeiten. Um gleichzeitig an einer anderen Funktion zu arbeiten, gehen Sie wie folgt vor:
Jetzt können Sie die Datei z.txt bearbeiten. So wechseln Sie zurück zu a.txt:
Aber warten Sie, es gibt Änderungen an new-feature-z und mit git können Sie keine Zweige wechseln. An diesem Punkt haben Sie zwei Möglichkeiten. Der erste ist der einfachste. Übernehmen Sie alle Änderungen in den aktuellen Zweig:
Das würde ich empfehlen. Wenn Sie jedoch wirklich nicht bereit sind, den Code festzuschreiben, können Sie ihn vorübergehend aufbewahren:
Jetzt können Sie zum Zweig new-feature-a wechseln. Um zu dem Code zurückzukehren, an dem Sie gearbeitet haben, legen Sie einfach den Stash ab:
Wenn alles erledigt ist, füge alle Änderungen zum Master zurück:
Weil Zusammenführungen so schnell und einfach sind (einfach, weil Konflikte so selten sind und Konfliktlösung, wenn es passiert, nicht zu schwer), verwenden wir Zweige in Git für alles.
Hier ist ein weiteres Beispiel für eine häufige Verwendung von Zweigen in Git, die Sie in anderen Quellcodeverwaltungs-Tools nicht sehen (außer vielleicht mercurial):
Müssen Sie Ihre Konfigurationsdateien ständig ändern, um Ihre Entwicklungsumgebung widerzuspiegeln? Dann benutze einen Zweig:
Bearbeiten Sie nun Ihre Konfigurationsdateien in Ihrem bevorzugten Editor und übernehmen Sie die folgenden Änderungen:
Jetzt kann jeder neue Zweig vom dev-config-Zweig anstelle von master starten:
Wenn Sie fertig sind, entfernen Sie die Änderungen in dev-config mithilfe der interaktiven Rebase aus dem Zweig für neue Funktionen:
Löschen Sie die Commits, die Sie nicht möchten, und speichern Sie sie. Jetzt haben Sie einen sauberen Zweig ohne benutzerdefinierte Konfigurationsänderungen. Zeit, sich wieder dem Master anzuschließen:
Es ist zu beachten, dass das Entfernen von Änderungen mit
git rebase -i
gerade funktioniert, wenn alle Änderungen in derselben Datei vorgenommen werden. Git merkt sich Änderungen, nicht den Dateiinhalt *.* Hinweis: Eigentlich technisch nicht ganz richtig, aber als Benutzer fühlt es sich so an
Weitere zusätzliche Antwort:
Aus Ihren Kommentaren geht hervor, dass zwei Zweige gleichzeitig existieren sollen, damit Sie testen können, wie der kombinierte Code funktioniert. Dies ist ein guter Weg, um die Leistungsfähigkeit und Flexibilität von Branchen zu veranschaulichen.
Zunächst ein Wort zur Auswirkung billiger Verzweigungen und veränderbarer Historien auf Ihren Workflow. Wenn ich CVS und SVN verwendete, war ich immer etwas zurückhaltend. Das liegt daran, dass das Festschreiben von instabilem Code unweigerlich den Arbeitscode anderer Leute beeinträchtigen würde. Aber mit git habe ich diese Angst verloren. Das liegt daran, dass in git andere Leute meine Änderungen erst erhalten, wenn ich sie zum Master zusammenführe. Jetzt schreibe ich alle 5 Zeilen, die ich schreibe, Code. Sie brauchen keine perfekte Voraussicht, um sich zu verpflichten. Sie müssen nur Ihre Denkweise ändern: Commit-to-Branch == Add-to-Changeset, Merge-to-Master == Commit-Changeset.
Also zurück zu den Beispielen. So würde ich es machen. Angenommen, Sie haben einen Zweig
new-feature-z
und möchten ihn testennew-feature-a
. Ich würde einfach einen neuen Zweig erstellen, um ihn zu testen:Jetzt können Sie testen. Wenn Sie etwas ändern müssen, damit Feature-Z mit Feature-A funktioniert, tun Sie dies. In diesem Fall können Sie die Änderungen in den entsprechenden Zweig zurückführen. Verwenden Sie
git rebase -i
diese Option , um irrelevante Änderungen aus der Zusammenführung zu entfernen.Alternativ können Sie auch git rebase verwenden, um die Basis von new-feature-z vorübergehend so zu ändern, dass sie auf new-feature-a verweist:
Jetzt wird der Zweigverlauf so geändert, dass new-feature-z auf new-feature-a anstelle von master basiert. Jetzt können Sie testen. Alle in diesem Zweig festgeschriebenen Änderungen gehören zum Zweig new-feature-z. Wenn Sie die neue Funktion ändern müssen, wechseln Sie einfach zurück und zur Basis, um die neuen Änderungen zu erhalten:
Wenn Sie fertig sind, kehren Sie einfach zum Master zurück, um Änderungen von new-feature-a zu entfernen:
Haben Sie keine Angst, eine neue Niederlassung zu gründen. Haben Sie keine Angst, einen Wegwerfzweig zu gründen. Hab keine Angst, Äste wegzuwerfen. Und da merge == submit and commit == Add-to-Changeset keine Angst davor hat, häufig festzuschreiben. Denken Sie daran, Commit ist das ultimative Rückgängig-Tool eines Entwicklers.
Oh, und noch etwas, in Git sind noch gelöschte Zweige in Ihrem Repository vorhanden. Wenn Sie also versehentlich etwas gelöscht haben, von dem Sie später feststellen, dass es nützlich ist, können Sie es jederzeit durch Durchsuchen des Verlaufs zurückerhalten. Hab keine Angst, Äste wegzuwerfen.
quelle
Ich habe nicht genug Erfahrung mit p4, um einen tatsächlichen Spickzettel zu erstellen, aber es gibt zumindest einige Ähnlichkeiten, auf die ich zurückgreifen kann. Ein p4 "Changeset" ist ein Git "Commit".
Änderungen an Ihrem lokalen Arbeitsbereich werden dem "Index" mit hinzugefügt
git add
, und der Index wird später mit festgeschriebengit commit
. Der Index ist also in jeder Hinsicht Ihre ausstehende Änderungsliste.Sie betrachten Änderungen mit
git diff
undgit status
, wobeigit diff
normalerweise Änderungen zwischen dem Arbeitsbereich und dem Index angezeigt werden, jedochgit diff --cached
Änderungen zwischen dem Index und dem Repository (= Ihre ausstehende Änderungsliste).Für ausführlichere Informationen empfehle ich http://progit.org/book/ . Da Sie die Versionskontrolle im Allgemeinen kennen, können Sie wahrscheinlich viel davon überfliegen und die git-spezifischen Informationen extrahieren ...
quelle
Ich leide wie Sie unter dem Fehlen des "Changelist" -Konzepts, das nicht genau mit Git-Zweigen identisch ist.
Ich würde ein kleines Skript schreiben, das eine Änderungslistendatei mit der Liste der Dateien in dieser Änderungsliste erstellt.
Ein weiterer Befehl, um nur eine bestimmte Änderungsliste zu senden, indem Sie einfach git commit -a @ change_list_contents.txt und dann "git commit" aufrufen.
Hoffe das hilft, Elias
quelle
Es gibt eine leichtere Alternative in Git, die Teil Ihres Workflows sein könnte. Verwenden des Git-Staging-Bereichs.
Ich nehme oft nur Änderungen vor und sende sie dann als mehrere Commits (z. B. Debug-Anweisungen hinzufügen, Refactor, tatsächlich einen Fehler beheben). Anstatt Ihre Perforce-Änderungslisten einzurichten, dann Änderungen vorzunehmen und dann zu senden, können Sie einfach Ihre Änderungen vornehmen und dann auswählen, wie sie gesendet werden sollen (optional über den Git-Staging-Bereich).
Sie können bestimmte Dateien über die Befehlszeile festschreiben mit:
Oder stellen Sie die Dateien zuerst explizit bereit:
Mit Git GUI können Sie Zeilen oder Hunks aus Dateien auswählen, um ein Commit im Staging-Bereich aufzubauen. Dies ist sehr nützlich, wenn Sie Änderungen an einer Datei haben, die in verschiedenen Commits enthalten sein sollen. Von git zu perforiert gewechselt zu sein und das ist eine Sache, die ich wirklich vermisse.
Bei diesem Workflow ist eine kleine Einschränkung zu beachten. Wenn Sie Änderungen A und B an einer Datei vornehmen, die Datei testen und dann A festschreiben, haben Sie diese Festschreibung nicht getestet (unabhängig von B).
quelle
Dies beantwortet Ihre Frage nicht speziell, aber ich weiß nicht, ob Sie wissen, dass eine 2-Benutzer-, 5-Arbeitsbereich-Version von perforce kostenlos von der perforce-Website heruntergeladen und verwendet werden kann .
Auf diese Weise können Sie perforce zu Hause für Ihre persönlichen Projekte verwenden, wenn Sie dies wünschen. Das einzige Ärgernis sind die 5 Arbeitsbereiche, die etwas einschränkend sein können, aber es ist ziemlich unglaublich, dass Perforce für den Heimgebrauch verfügbar ist.
quelle
Nachdem ich sowohl Perforce als auch Git ziemlich häufig verwendet habe, gibt es nur einen Weg, wie ich mit Git irgendwo in die Nähe von Perforce-Änderungslisten gelangen kann.
Das erste, was zu verstehen ist, ist, dass die korrekte Implementierung dieser Funktionalität in git so, dass es sich nicht um eine vollständige Kluge handelt, z. B. der Versuch, sie in Zweige zu zerlegen, die folgende Änderung erfordert: git würde mehrere Staging-Bereiche für einen einzelnen Zweig erfordern .
Perforce-Änderungslisten ermöglichen einen Workflow, der in git einfach kein Äquivalent hat. Betrachten Sie den folgenden Workflow:
Wenn Sie versuchen, dies mit Zweigen in Git zu tun, werden Sie zwei Zweige erhalten, von denen einer die Änderungen an der Datei enthält
A
, der andere die Änderungen an der DateiB
, aber keinen Ort, an dem Sie die Änderungen an beiden DateienA
undB
unter sehen können die selbe Zeit.Die nächste Annäherung, die ich sehen kann, besteht darin,
git add . -p
die Unterbefehle'a'
und zu verwenden und dann zu verwenden'd'
, um ganze Dateien auszuwählen oder abzulehnen. Dies ist jedoch nicht ganz dasselbe, und der Unterschied ergibt sich aus einer grundlegenden Ungleichheit in der allgemeinen Funktionsweise der beiden Systeme.Git (und Subversion, nicht dass es für diese Diskussion wichtig ist) ermöglichen es, eine Datei zu ändern, ohne vorher jemandem davon zu erzählen. Sie ändern einfach eine Datei und lassen git alles sortieren, wenn Sie die Änderungen festschreiben. Perforce erfordert, dass Sie eine Datei aktiv auschecken, bevor Änderungen zulässig sind. Aus diesem Grund müssen Änderungslisten vorhanden sein. Perforce erfordert im Wesentlichen, dass Sie dem Index eine Datei hinzufügen, bevor Sie sie ändern. Daher die Notwendigkeit mehrerer Änderungslisten in Perforce und auch der Grund, warum Git kein Äquivalent hat. Es braucht sie einfach nicht.
quelle
Mit Git 2.27 (Q2 2020) lernte "
git p4
" vier neue Hooks und auch die--no-verify
Option " ", sie (und den vorhandenen "p4-pre-submit
" Hook) zu umgehen .Siehe Commit 1ec4a0a , Commit 38ecf75 , Commit cd1e0dc (14. Februar 2020) und Commit 4935c45 , Commit aa8b766 , Commit 9f59ca4 , Commit 6b602a2 (11. Februar 2020) von Ben Keene (
seraphire
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit 5f2ec21 , 22. April 2020)Vor Git 2.28 (Q3 2020) soll die
--prepare-p4-only
Option " " nach der Wiedergabe eines Änderungssatzes beendet werden, aber (versehentlich?) Weitergeführt werden.Siehe Commit 2dfdd70 (12. Mai 2020) von Ben Keene (
seraphire
) .(Zusammengeführt von Junio C Hamano -
gitster
- in Commit 7a8fec9 , 02. Juni 2020)quelle