2009-09-05 3 views
270

Während ich heute einem Freund mit einem git-Problem geholfen habe, musste ich einen -Zweig einführen, der komplett vom Zweig master getrennt sein musste. Der Inhalt dieses Zweiges hatte tatsächlich einen anderen Ursprung als wurde auf dem Zweig master entwickelt, aber sie wurden zu einem späteren Zeitpunkt in den Zweig master zusammengeführt werden.Gibt es in git eine einfache Möglichkeit, einen nicht verwandten Zweig in ein Repository einzuführen?

ich John Wiegley der Erinnerung aus der Lektüre Git from the bottom up wie Zweige sind im Wesentlichen ein Etikett zu einem Commit, dass eine bestimmte wird folgt Konvention und wie ein Commit an einen Baum von Dateien gebunden und optional Mutter verpflichtet. Wir gingen ein elternlos zu schaffen, um die vorhandenen Repository git des Sanitär-commit:

Also haben wir alle Dateien im Index befreien ...

$ git rm -rf . 

... extrahierten Verzeichnisse und Dateien von einem Tarball , hinzugefügt, um den Index diejenigen ...

$ git add . 

... und ein Baumobjekt erstellt ...

$ git write-tree 

(git-write-tree sagte uns der sha1sum des Baumes Objekt erstellt.)

Dann wir den Baum verpflichtet, ohne Angabe von Eltern verpflichtet ...

$ echo "Imported project foo" | git commit-tree $TREE 

(git-commit-tree uns gesagt, die sha1sum der erstellten Commit-Objekt.)

... und einen neuen Zweig erstellt, der auf unser neu erstelltes commit verweist.

$ git update-ref refs/heads/other-branch $COMMIT 

Endlich sind wir zum Zweig master zurückgekehrt, um dort weiter zu arbeiten.

$ git checkout -f master 

Dies scheint wie geplant gearbeitet zu haben. Aber das ist eindeutig nicht die Art der Prozedur, die ich jemandem empfehlen würde, der nur mit Git beginnt, um es milde auszudrücken. Gibt es eine einfachere Möglichkeit, einen neuen Zweig zu erstellen, der völlig unabhängig von allem ist, was im Repository bisher passiert ist?

Antwort

420

Es gibt ein neues Feature (seit V1.7.2), das diese Aufgabe etwas höher als in den anderen Antworten macht.

git checkout unterstützt jetzt die Option --orphan Option. Von der man page:

git checkout [-q] [-f] [-m] --orphan <new_branch> [<start_point>]

Erstellen Sie ein neues Waise Zweig namens <new_branch> begann von <start_point> und wechseln Sie es. Die erste commit auf dieser neuen Niederlassung gemacht wird keine Eltern haben und es wird die Wurzel einer neuen Geschichte total von allen anderen Zweige und Commits getrennt werden.

Dies gilt nicht genau was der Fragesteller wollte, weil es den Index und den Arbeits Baum von <start_point> (da dies immerhin eine Kasse Befehl) auffüllt. Die einzige andere erforderliche Aktion ist das Entfernen unerwünschter Elemente aus der Arbeitsbaumstruktur und dem Index. Leider funktioniert git reset --hard nicht, aber git rm -rf . kann stattdessen verwendet werden (ich glaube, das entspricht rm .git/index; git clean -fdx in anderen Antworten gegeben).


Zusammengefasst:

git checkout --orphan newbranch 
git rm -rf . 
<do work> 
git add your files 
git commit -m 'Initial commit' 

verließ ich <start_point> nicht näher bezeichnet, weil es standardmäßig HEAD, und wir wirklich sowieso egal. Diese Sequenz funktioniert im Wesentlichen genauso wie die Befehlssequenz in Artem's answer, ohne auf furchterregende Klimmzugbefehle zurückgreifen zu müssen.

+19

Hinweis: Diese Funktion wurde in git 1.7.2 hinzugefügt. – Matthew

+0

Wissen Sie, ob es möglich ist, einen verwaisten Zweig zu erstellen, der sichtbar bleibt, wenn Sie einen Zweig aus dem anderen "Baum" auschecken? – JJD

+1

@JJD: Ich denke, was Sie wollen, ist Git fusionieren. '(git checkmaster && git merge --no-commit" Orphan-branch ")' Einige ähnliche Tricks funktionieren mit git-reset oder spielen mit dem Index. Aber es hängt von Ihrem gewünschten Workflow ab. – phord

30

Von Git Community Book:

git symbolic-ref HEAD refs/heads/newbranch 
rm .git/index 
git clean -fdx 
<do work> 
git add your files 
git commit -m 'Initial commit' 
+3

Dies ist eine großartige Antwort. – gahooa

+1

Nächste Antwort ist besser für moderne Versionen von Git. – kikito

+10

@kikito: Re: "Nächste Antwort ist besser" ... Die Bestellung hier auf SO ist nicht stabil. Könnten Sie einen Link hinzufügen, der auf eine bessere Antwort verweist? –

12

Github hat eine Funktion namens Project Pages wo Sie eine bestimmte Namen Niederlassung in Ihrem Projekt erstellen können Dateien zur Verfügung zu stellen, die von Github serviert wird. Ihre Anweisungen lauten wie folgt:

Von dort haben Sie ein leeres Repository, dem Sie dann Ihren neuen Inhalt hinzufügen können.

21

Obwohl die Lösung mit git symbolic-ref und Index-Werke zu entfernen, könnte es konzeptionell sauberere sein neue Repository erstellen

$ cd /path/to/unrelated 
$ git init 
[edit and add files] 
$ git add . 
$ git commit -m "Initial commit of unrelated" 
[master (root-commit) 2a665f6] Initial commit of unrelated 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 foo 

dann holen daraus

$ cd /path/to/repo 
$ git fetch /path/to/unrelated master:unrelated-branch 
warning: no common commits 
remote: Counting objects: 3, done. 
Unpacking objects: 100% (3/3), done. 
remote: Total 3 (delta 0), reused 0 (delta 0) 
From /path/to/unrelated 
* [new branch]  master  -> unrelated-branch 

Jetzt können Sie löschen/Weg/zu/nicht verwandt

+0

Meiner Meinung nach würde ein sauberes Konzept die Option "git branch" oder "git checkout" beinhalten. Ich bin froh, dass Git solche Dinge möglich macht, aber warum sollte es nicht einfacher sein? – hillu

+3

Weil es ist, und sollte eine seltene Sache sein. Wenn Sie nicht verwandte Dinge Zweig haben, gehört es in der Regel zu nicht verwandten Repository, anstatt es in bestehende Repository (obwohl es Ausnahmen gibt). –

+1

+1. Für andere Git-Neulinge können Sie die Zweige dann scheinbar über 'git branch' auflisten und zwischen ihnen über' git checkout BRANCH_NAME' wechseln. – akavel

0

Gefunden thi s Skript um http://wingolog.org/archives/2008/10/14/merging-in-unrelated-git-branches und es funktioniert sehr gut!

#!/bin/bash 

set -e 

if test -z "$2" -o -n "$3"; then 
    echo "usage: $0 REPO BRANCHNAME" >&2 
    exit 1 
fi 

repo=$1 
branch=$2 

git fetch "$repo" "$branch" 

head=$(git rev-parse HEAD) 
fetched=$(git rev-parse FETCH_HEAD) 
headref=$(git rev-parse --symbolic-full-name HEAD) 

git checkout $fetched . 

tree=$(git write-tree) 

newhead=$(echo "merged in branch '$branch' from $repo" | git commit-tree $tree -p $head -p $fetched) 
git update-ref $headref $newhead $head 
git reset --hard $headref 
+1

Ich glaube, dass der gleiche Effekt erreicht werden kann mit 'git fetch $ REMOTE $ REMOTE_BRANCH: $ LOCAL_BRANCH'. Fehle ich etwas? – hillu

2

Manchmal mag ich nur leeren Zweig in Projekt beginnt sofort dann schaffen, Arbeit zu tun, werde ich folgenden Befehl nur excute:

git checkout --orphan unrelated.branch.name 
git rm --cached -r . 
echo "init unrelated branch" > README.md 
git add README.md 
git commit -m "init unrelated branch" 
Verwandte Themen