2010-04-21 2 views
9

Ich versuche, einen Darcs-Spiegel eines Git-Repository einzurichten. Ich habe etwas, das funktioniert OK, aber es gibt ein signifikantes Problem: Wenn ich eine ganze Reihe von Commits zum Git Repo drücke, werden diese Commits in einem einzigen Darcs Patchset zusammengeführt. Ich möchte wirklich sicherstellen, dass jedes Git-Commit als ein einzelnes Darcs-Patchset eingerichtet wird. Ich wette, das ist möglich, indem ich eine Art von git fetch gefolgt von der Abfrage der lokalen Kopie der Remote-Zweigstelle, aber meine git fu ist nicht an die Aufgabe.Wie wird ein Commit nach dem anderen aus einem Remote-Git-Repository abgerufen?

Hier ist die (KSH) -Code ich jetzt benutze, mehr oder weniger:

git pull -v # pulls all the commits from remote --- bad! 

# gets information about only the last commit pulled -- bad! 
author="$(git log HEAD^..HEAD --pretty=format:"%an <%ae>")" 
logfile=$(mktemp) 
git log HEAD^..HEAD --pretty=format:"%s%n%b%n" > $logfile 

# add all new files to darcs and record a patchset. this part is OK 
darcs add -q --umask=0002 -r . 
darcs record -a -A "$author" --logfile="$logfile" 
darcs push -a 
rm -f $logfile 

Meine Idee

  1. Versuchen git fetch ist die lokale Kopie des Remote-Zweiges zu erhalten (nicht sicher, genau welche Argumente benötigt werden)
  2. Irgendwie die lokale Kopie abfragen, um einen Hash für jedes Festschreiben seit der letzten Spiegelungoperation zu erhalten (ich habe keine Idee, wie man das tut)
  3. Schleife durch alle Hashes, ziehen nur, dass begehen und die Aufzeichnung der zugehörigen Patchset (ich bin mir ziemlich sicher, dass ich weiß, wie dies zu tun, wenn ich meine Hände auf den Hash bekommen)

Ich würde gern gesehen entweder Hilfe fleshing aus dem Szenario über oder Vorschläge über etwas anderes sollte ich versuchen.

Ideen?

+0

Nur zur Erinnerung, es gibt ein paar neue Antworten, die Sie nicht kommentiert haben. (Offensichtlich einer von ihnen, denke ich, beantwortet Ihre Frage wirklich besonders gut;)) –

Antwort

0

git remote update # fetch all remotes I like it better than just fetch

git log origin/master # can be any remote/branch

git cherry-pick origin/master # example remote/branch you can also specify a sha1

cherry-pick die Top-Patch standardmäßig auswählen.

für den dritten Teil Ich denke, Sie müssen ein Skript schreiben, um es für Sie zu tun. Es gibt andere Möglichkeiten, die Hashes und viele Optionen für das Protokoll zu erhalten. Eigentlich könnte es einen Haken für cherry-pick geben oder einfach post commit ... um den darcs-code laufen zu lassen. Schau dir Git Haken an.

In der Tat könnte jeder Patch in einer Rebase einen git commit Hook aufrufen, so dass Sie in der Lage sein könnten, das zu schreiben und dann einen git pull --rebase ausführen und den Code für jede Anwendung genagelt haben ...

+0

+1 für die Zitierung githooks. – jweyrich

+1

Ich habe Informationen im Web für 'git cherry-pick' studiert, und es ist nicht, was ich überhaupt will! Es schafft ein neues, eindeutiges Commit! Ich werde tiefer graben. –

0

Mit dieser Hashes von einem Zweig abzurufen:

git log --pretty=format:"%h" HEAD..origin/master 

Dann git cherry-pick -n <hash> jeder anwenden verwenden.

Eine andere Option, wie von @xenoterracide zitiert, ist die Verwendung von githooks.

+4

Ich habe Informationen im Web für 'git cherry-pick' studiert, und es ist nicht das, was ich überhaupt will! Es schafft ein neues, eindeutiges Commit! Ich werde tiefer graben. –

2

Haben Sie versucht, einige vorhandene Lösungen zum Verschieben von Änderungssätzen zwischen Versionskontrollsystemen zu betrachten, z. B. Tailor, die besagt, dass es Unterstützung für Git und Darcs bietet? (Es gibt Vorschläge für ähnliche Systeme auf dieser Seite als auch.)

Andernfalls, wenn Sie Ihren vorgeschlagene Ansatz verwenden mögen, können Sie git checkout auf jedem Commit nach HEAD-origin/master zur Kasse verwenden könnten, den Modus in „detached HEAD“ commit .Um zum Beispiel das Beispiel, das Sie geben zu modifizieren (und in der Bourne-Shell, fürchte ich, da ich nicht ksh verwenden):

# Update all remote-tracking branches from origin 
git fetch origin 

for c in `git log --pretty=format:"%h" HEAD..origin/master` 
do 
    git checkout $c 
    author=$(git log -1 --pretty=format:"%an <%ae>") 
    logfile=$(mktemp) 
    git log -1 --pretty=format:"%s%n%n%b%n" > $logfile 

    darcs add -q --umask=0002 -r . 
    darcs record -a -A "$author" --logfile="$logfile" 
    darcs push -a 
    rm -f $logfile   
done 

# Now go back to master, and merge to keep your master branch up to date: 
git checkout master 
git merge origin/master 

Beachten Sie, dass dies die Geschichte von git linearisieren wird, die nicht wollten, was ich wollte, persönlich. :) Ich denke, es ist am besten, ein bestehendes Tool dafür zu verwenden, aber der obige Ansatz könnte funktionieren.

1

Man könnte so etwas tun:

#!/bin/bash 
git fetch 
count=$(git log --pretty=oneline | wc -l) 
git merge origin/master 
git reset --hard HEAD~$((count-1)) 

Ich habe ein Repository für dieses Skript und ausprobiert. Hier finden Sie vor und nach der Zusammenführung:

enter image description here

enter image description here

Jetzt habe ich keine Remote-Repository hat so gefälscht ich die git holen und den Remote-Zweig mit einer lokalen (benannt kalle), aber Du hast die Idee. Führen Sie einfach die vollständige Zusammenführung durch und sichern Sie dann den HEAD-Zeiger, bis Sie die erste Übergabe vom Ursprung/Master erreichen.

Verwandte Themen