In git, c’è un modo semplice per introdurre un ramo non correlato in un repository?

Mentre aiutavo un amico con un problema git oggi, ho dovuto introdurre un ramo che doveva essere completamente separato dal ramo master . I contenuti di questo ramo hanno avuto un’origine diversa da quella che era stata sviluppata sul ramo master , ma in seguito sarebbero stati incorporati nel ramo master .

Mi sono ricordato leggendo il Git di John Wiegley dal basso verso l’alto su come i rami sono essenzialmente un’etichetta per un commit che segue una certa convenzione e come un commit è legato a un albero di file e, opzionalmente, ai commit del genitore. Siamo andati a creare un commit parentless nel repository esistente utilizzando l’impianto idraulico di git:

Quindi ci siamo sbarazzati di tutti i file nell’indice …

 $ git rm -rf . 

… ha estratto le directory e i file da un tarball, li ha aggiunti all’indice …

 $ git add . 

… e creato un object ad albero …

 $ git write-tree 

( git-write-tree ci ha detto lo sha1sum dell’object tree creato).

Quindi, abbiamo commesso l’albero, senza specificare i commit del genitore …

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

( git-commit-tree ci ha detto lo sha1sum dell’object commit creato).

… e creato un nuovo ramo che punta al nostro commit appena creato.

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

Alla fine, siamo tornati al master per continuare a lavorare lì.

 $ git checkout -f master 

Questo sembra aver funzionato come previsto. Ma questo non è chiaramente il tipo di procedura che raccomanderei a qualcuno che sta appena iniziando a usare git, per usare un eufemismo. C’è un modo più semplice per creare un nuovo ramo che non sia interamente correlato a tutto ciò che è accaduto finora nel repository?

C’è una nuova funzione (dalla V1.7.2) che rende questo compito un po ‘più di alto livello di quello che c’è in una delle altre risposte.

git checkout ora supporta l’opzione --orphan . Dalla pagina man :

git checkout [-q] [-f] [-m] --orphan []

Crea un nuovo ramo orfano , denominato , avviato da e passa ad esso. Il primo impegno fatto su questo nuovo ramo non avrà genitori e sarà la radice di una nuova storia totalmente disconnessa da tutti gli altri rami e commit.

Questo non fa esattamente quello che voleva il richiedente, perché popola l’indice e l’albero di lavoro da (poiché questo è, dopo tutto, un comando di checkout). L’unica altra azione necessaria è rimuovere tutti gli oggetti indesiderati dall’albero di lavoro e dall’indice. Sfortunatamente, git reset --hard non funziona, ma git rm -rf . può essere usato invece (credo che questo sia equivalente a rm .git/index; git clean -fdx dato in altre risposte).


In sintesi:

 git checkout --orphan newbranch git rm -rf .  git add your files git commit -m 'Initial commit' 

Ho lasciato non specificato perché è su HEAD e non ci interessa molto. Questa sequenza fa essenzialmente la stessa cosa della sequenza di comando nella risposta di Artem , semplicemente senza ricorrere a comandi idraulici spaventosi.

Da Git Community Book :

 git symbolic-ref HEAD refs/heads/newbranch rm .git/index git clean -fdx  git add your files git commit -m 'Initial commit' 

Sebbene la soluzione con git symbolic-ref e la rimozione dell’indice funzionino, potrebbe essere concettualmente più pulito creare un nuovo repository

 $ 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 

quindi prendi da esso

 $ 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 

Ora puoi cancellare / percorso / per / non correlato

Github ha una funzione chiamata Pagine di progetto in cui puoi creare una particolare diramazione con nome nel tuo progetto per fornire file che saranno serviti da Github. Le loro istruzioni sono le seguenti:

 $ cd /path/to/fancypants $ git symbolic-ref HEAD refs/heads/gh-pages $ rm .git/index $ git clean -fdx 

Da lì hai un repository vuoto a cui puoi aggiungere il tuo nuovo contenuto.

La risposta attualmente selezionata è corretta, vorrei solo aggiungere che per coincidenza …

Questo è in realtà esattamente come github.com consente agli utenti di creare Github Pages per i loro repository, attraverso un ramo orfano chiamato gh-pages . I bei passaggi sono dati e spiegati qui:

https://help.github.com/articles/creating-project-pages-manually

Spero che questo ti aiuti!

A volte voglio solo creare un ramo vuoto nel progetto all’istante, quindi iniziare a fare il lavoro, eseguirò il comando seguente:

 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" 

Ho trovato questo script su http://wingolog.org/archives/2008/10/14/merging-in-unrelated-git-branches e funziona molto bene!

 #!/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 

Se il tuo contenuto esistente era già impegnato, ora (Git 2.18 Q2 2018) puoi estrarlo nel suo nuovo ramo orfano, poiché l’implementazione di ” git rebase -i --root ” è stata aggiornata per utilizzare di più il macchinario del sequencer.

Quel sequencer è quello che ora permette di trapiantare l’intera topologia del grafico di commit altrove .

Vedi commit 8fa6eea , commit 9c85a1c , commit ebddf39 , commit 21d0764 , commit d87d48b , commit ba97aea (03 maggio 2018) di Johannes Schindelin ( dscho ) .
(Fuso da Junio ​​C Hamano – gitster – in commit c5aa4bc , 30 maggio 2018)

sequencer: consentire l’introduzione di nuovi commit di root

Nel contesto della nuova modalità --rebase-merges , che è stata progettata appositamente per consentire di modificare liberamente la topologia del ramo esistente, un utente potrebbe voler estrarre commit in un ramo completamente nuovo che inizia con un commit radice appena creato .

Questo è ora ansible inserendo il comando reset [new root] prima di pick il commit che vuole diventare un commit di root. Esempio:

 reset [new root] pick 012345 a commit that is about to become a root commit pick 234567 this commit will have the previous one as parent 

Ciò non è in conflitto con altri usi del comando reset perché [new root] non è (parte di) un nome di riferimento valido: sia la parentesi di apertura che lo spazio sono illegali nei nomi di riferimento.