Se corro git branch -d XYZ
, c'è un modo per recuperare il ramo? C'è un modo per tornare indietro come se non avessi eseguito il comando delete branch?
Se corro git branch -d XYZ
, c'è un modo per recuperare il ramo? C'è un modo per tornare indietro come se non avessi eseguito il comando delete branch?
Risposte:
Sì, dovresti essere in grado di fare git reflog
e trovare SHA1 per il commit sulla punta del tuo ramo eliminato, quindi solo git checkout [sha]
. E una volta che sei a quel commit, puoi semplicemente git checkout -b [branchname]
ricreare il ramo da lì.
Ringraziamo @Cascabel per questa versione ridotta / one-liner.
Puoi farlo in un solo passaggio:
git checkout -b <branch> <sha>
git checkout -b <branch> <sha>
.
<sha>
. Ad esempio, come menzionato sopra -git checkout -b <branch> <sha>
CMD+K
)
git reflog --no-abbrev
per vedere il completo <sha>
abbreviato per impostazione predefinita.
git checkout remotes/origin/deleted_branch
.
La maggior parte delle volte i commit non raggiungibili sono nel reflog. Quindi, la prima cosa da provare è guardare il reflog usando il comando git reflog
(che mostra il reflog per HEAD
).
Forse qualcosa di più semplice se il commit fosse parte di un ramo specifico ancora esistente è usare il comando git reflog name-of-my-branch
. Funziona anche con un telecomando, ad esempio se hai forzato la spinta (consiglio aggiuntivo: preferisci sempregit push --force-with-lease
piuttosto prevenire meglio errori ed è più recuperabile).
Se i tuoi commit non sono nel tuo reflog (forse perché cancellati da uno strumento di terze parti che non scrive nel reflog), ho recuperato con successo un ramo resettando il mio ramo allo sha del commit trovato usando un comando come quello (esso crea un file con tutti i commit sospesi):
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
Se dovessi usarlo più di una volta (o vuoi salvarlo da qualche parte), potresti anche creare un alias con quel comando ...
git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'
e usalo con git rescue
Per esaminare i commit trovati, è possibile visualizzare ciascun commit utilizzando alcuni comandi per esaminarli.
Per visualizzare i metadati di commit (autore, data di creazione e messaggio di commit):
git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
Per vedere anche le differenze:
git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
Una volta trovato il commit, quindi creare un ramo su questo commit con:
git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560
Per quelli che si trovano in Windows e amano le GUI, puoi facilmente recuperare i commit (e anche i file in staging senza commit) con GitExtensions utilizzando la funzione Repository
=>Git maintenance
=>Recover lost objects...
Un comando simile per recuperare facilmente i file in fasi eliminati: https://stackoverflow.com/a/58853981/717372
Se ti piace usare una GUI, puoi eseguire l'intera operazione con gitk.
gitk --reflog
Ciò ti consentirà di visualizzare la cronologia di commit del ramo come se il ramo non fosse stato eliminato. Ora fai semplicemente clic con il pulsante destro del mouse sul commit più recente per il ramo e seleziona l'opzione di menu Create new branch
.
La soluzione più votata in realtà fa più di quanto richiesto:
git checkout <sha>
git checkout -b <branch>
o
git checkout -b <branch> <sha>
spostarti nella nuova filiale insieme a tutte le modifiche recenti che potresti aver dimenticato di impegnare. Questa potrebbe non essere la tua intenzione, specialmente quando sei in "modalità panico" dopo aver perso il ramo.
Una soluzione più pulita (e più semplice) sembra essere quella di una linea (dopo aver trovato il <sha>
con git reflog
):
git branch <branch> <sha>
Ora non sono interessati né il ramo corrente né le modifiche non impegnate. Invece verrà creato solo un nuovo ramo fino al<sha>
.
Se non è la punta, funzionerà comunque e otterrai un ramo più corto, quindi puoi riprovare con nuovo <sha>
nome di ramo e nuovo fino a quando non lo ottieni nel modo giusto.
Finalmente puoi rinominare il ramo ripristinato con successo in come è stato chiamato o in qualsiasi altra cosa:
git branch -m <restored branch> <final branch>
Inutile dire che la chiave del successo era trovare il giusto commit <sha>
, quindi dai un nome saggio ai tuoi commit :)
Aggiungendo alla risposta tfe : c'è anche lo script git-resurrect.shcontrib/
nell'area delle fonti Git (nel repository git.git), che potrebbe aiutarti.
git-resurrect <name>
tenta di trovare tracce di un ramo chiamato<name>
e cerca di resuscitarlo. Attualmente, il reflog viene cercato per i messaggi di checkout e-r
anche per unire i messaggi. Con-m
e-t
, la storia di tutti i riferimenti viene scansionata perMerge <name> into other
/Merge <other> into <name>
(rispettivamente) impegnare soggetti, che è piuttosto lento ma consente di resuscitare rami di argomenti di altre persone.
Ho usato i seguenti comandi per trovare e recuperare il mio ramo cancellato. I primi passi sono dalla descrizione di gcb.
$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\ -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline
Ora cerca l'id di commit git (GIT-SHA) in base ai commenti di commit e usalo nel comando seguente. Acquista una nuova filiale chiamata NEW-BRANCH con il GIT-SHA precedentemente trovato:
$ git checkout -b NEW-BRANCH GIT-SHA
Se non si dispone di un reflog, ad es. poiché stai lavorando in un repository nudo che non ha il reflog abilitato e il commit che vuoi recuperare è stato creato di recente, un'altra opzione è quella di trovare oggetti commit creati di recente e guardarli.
Dall'interno della .git/objects
directory eseguire:
find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit
Trova tutti gli oggetti (commit, file, tag ecc.) Creati nelle ultime 12 ore e li filtra per mostrare solo i commit. Il controllo di questi è quindi un processo rapido.
Tuttavia, proverei prima lo script git-ressurect.sh menzionato nella risposta di Jakub .
man find
: "-ctime n - Lo stato del file è stato modificato l'ultima volta n * 24 ore fa." Quindi dovremmo anche cambiare da 12 a 0,5 per avere il comportamento previsto delle ultime 12 ore.
Per gli utenti GitHub senza Git installato:
Se si desidera ripristinarlo dal sito Web GitHub , è possibile utilizzare la loro API per ottenere un elenco di eventi relativi al repository:
Primo
trova quegli SHA (commit hash):
curl -i https://api.github.com/repos/PublicUser/PublicRepo/events
... o per repository privati:
curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events
(verrà richiesta la password GitHub)
Il prossimo
• Vai ai rami ed elimina quello.
• Nella stessa pagina, senza ricaricare , aprire DevTools, pannello Rete. Ora prepara ...
• Fai clic su Ripristina. Noterai una nuova "linea". Fai clic destro su di esso e seleziona "Copia come cURL" e salva questo testo in alcuni editor.
• aggiungere alla fine della riga copiata di codice, questo: -H "Cookie="
.
Ora dovresti ottenere qualcosa del tipo:
curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed
Passo finale
PS
Mi rendo conto che questa potrebbe non essere la "soluzione più semplice" o la "giusta" soluzione, ma viene offerta nel caso in cui qualcuno la trovi utile.
git reflog
e quindi è stato utile, ad esempio, quando si è cancellato un ramo remoto e si è perso l'accesso al computer che è stato fatto in modo da non ottenere nulla di freddo utile reflog
. Nota quando usi OAuth o l'autenticazione a due fattori su Github il curl
comando diventa nel seguente modo: curl -u username:token https://api.github.com/user
oppurecurl -H "Authorization: token TOKEN" https://api.github.com/repos/USER_OR_ORG_NAME/REPO_NAME/events
Dalla mia comprensione se il ramo da eliminare può essere raggiunto da un altro ramo, è possibile eliminarlo in modo sicuro utilizzando
git branch -d [branch]
e il tuo lavoro non è perso. Ricorda che un ramo non è un'istantanea, ma un puntatore a uno. Quindi quando elimini un ramo elimini un puntatore.
Non perderai nemmeno lavoro se elimini un ramo che non può essere raggiunto da un altro. Ovviamente non sarà facile come controllare l'hash di commit, ma puoi ancora farlo. Ecco perché Git non è in grado di eliminare un ramo che non è possibile raggiungere utilizzando -d
. Invece devi usare
git branch -D [branch]
Questo fa parte di un must per guardare il video di Scott Chacon su Git. Controlla il minuto 58:00 quando parla dei rami e di come eliminarli.
reflog
sono semplicemente eccessive.
Assicurati di eseguire tutto ciò localmente e verifica che il tuo repository sia nello stato desiderato prima di inviare a Bitbucket Cloud. Potrebbe anche essere una buona idea clonare l'attuale repository e testare prima queste soluzioni.
Deleted branch <your-branch> (was <sha>)
2.Per ripristinare il ramo, utilizzare:
git checkout -b <branch> <sha>
Se non conosci lo "sha" dalla parte superiore della testa, puoi:
git reflog
git checkout -b <branch> <sha>
Se i tuoi commit non sono nel tuo reflog:
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
2.È quindi possibile visualizzare ciascun commit utilizzando uno di questi:
git log -p <commit>
git cat-file -p <commit>
Ho riassemblato un ramo da remoto per cercare di cancellare alcuni impegni che non volevo e avrei cercato di scegliere quelli giusti che volevo. Naturalmente ho sbagliato a scrivere gli SHA ...
Ecco come li ho trovati (principalmente un'interfaccia / interazione più semplice dalle cose sulle risposte qui):
Innanzitutto, genera un elenco di commit non registrati nel registro. Fallo il prima possibile e smetti di funzionare, poiché potrebbero essere scaricati dal garbage collector.
git fsck --full --no-reflogs --unreachable --lost-found > lost
Questo crea un lost
file con tutti i commit che dovrai osservare. Per semplificare la nostra vita, tagliamo solo lo SHA da esso:
cat lost | cut -d\ -f3 > commits
Ora hai un commits
file con tutti i commit che devi guardare.
Supponendo che tu stia usando Bash, il passaggio finale:
for c in `cat commits`; do git show $c; read; done
Questo ti mostrerà le informazioni di diff e commit per ognuna di esse. E aspetta che tu prema Enter. Ora scrivi tutti quelli che vuoi e poi selezionali. Dopo aver finito, basta premere Ctrl-C.
GRANDE SÌ
se stai usando GIT segui questi semplici passaggi https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html
se stai usando smartgit e già spingi quel ramo vai all'origine, trova quel ramo e fai clic con il tasto destro, quindi fai il checkout
Per prima cosa vai in git batch per passare al tuo progetto come:
cd android studio project
cd Myproject
then type :
git reflog
Tutti voi avete un elenco delle modifiche e il numero di riferimento prende il numero di riferimento, quindi fate il checkout
da Android Studio o dal Git Betcha. un'altra soluzione prende il numero di riferimento e vai su android studio fai clic sui rami git verso il basso, quindi fai clic sul tag checkout o sulla revisione oltre il numero di riferimento, quindi lol hai i rami.
Aggiungendo alla risposta di tfe, è possibile recuperare con questo processo menzionato, a meno che i suoi commit non siano garbage collection. Il ramo Git è semplicemente un puntatore a un particolare commit nella struttura di commit. Ma se si elimina il puntatore e i commit su quel ramo non vengono uniti in un altro ramo esistente, git lo considera come commit penzolanti e li rimuove durante la garbage collection, che può essere eseguita automaticamente periodicamente.
Se il tuo ramo non è stato unito a un ramo esistente e se è stata raccolta rifiuti, perderai tutti i commit fino al punto in cui il ramo è stato biforcato da un ramo esistente.
Un problema correlato: sono arrivato a questa pagina dopo aver cercato "come sapere quali sono i rami eliminati".
Durante l'eliminazione di molti rami vecchi, ho sentito di aver erroneamente cancellato uno dei rami più recenti, ma non conoscevo il nome per recuperarlo.
Per sapere quali rami sono stati eliminati di recente, procedi come segue:
Se vai al tuo URL Git, che sarà simile a questo:
https://your-website-name/orgs/your-org-name/dashboard
Quindi puoi vedere il feed, di ciò che viene eliminato, da chi, nel recente passato.
L'ho fatto sul computer che elimino il ramo:
git reflog
risposta:
74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git
e recupero il ramo con questo comando:
git checkout -b newBranchName 74b2383
Il solo utilizzo git reflog
non ha restituito il valore sha
per me. Solo il commit id
(che è lungo 8 caratteri e uno sha è molto più lungo)
Quindi ho usato
git reflog --no-abbrev
E poi fai lo stesso come menzionato sopra:
git checkout -b <branch> <sha>
Si noti che git branch delete elimina solo la copia locale, non la copia sul server. Innanzitutto, nel pannello Git (icona git sulla barra degli strumenti a sinistra), guarda tra i rami e vedi se il tuo ramo è ancora lì sotto "origine / nome_branco". In tal caso, selezionalo e dovresti recuperare il tuo codice (suggerisci di copiarlo / incollarlo / salvarlo localmente da qualche altra parte).
Se non hai visualizzato "origin / your_branch_name", installa l'estensione GitLens. Ciò consente di cercare visivamente nei repository del server e di individuare la copia sincronizzata con il server. Se hai più repository, tieni presente che potrebbe essere necessario aprire almeno un file dal repository desiderato per far apparire il repository in GitLens. Poi:
Apri il pannello GitLens
Espandi il repository
Dovresti vedere un elenco di categorie: Filiali / Collaboratori / Telecomandi / Stash / ecc
Dovresti trovare YourLostTreasure in "Filiali" o possibilmente in "Telecomandi -> Origini". Speriamo che vedrai un ramo con il nome desiderato - se lo espandi, dovresti vedere i file che hai cambiato in quel ramo. Fare doppio clic sui nomi dei file per aprirli e eseguire immediatamente il backup di quel codice.
Se non vedi immediatamente il tuo ramo perduto, cerca e se trovi qualcosa di promettente, aprilo immediatamente e prendi il codice. Ho dovuto curiosare un po 'fino a quando non ho trovato TheGoldenBranch, e anche allora il codice mancava l'ultimo o due salvataggi (forse perché non sono riuscito a sincronizzare con il server prima di provare a-Branch-Merge-ma-accidentalmente-clic- Branch-Delete). La mia ricerca è stata inutilmente allungata perché quando ho trovato il ramo per la prima volta non ero completamente sicuro che il nome fosse corretto, quindi continuavo a cercare e ci è voluto del tempo per ritrovare quel primo ramo. (Quindi, Carpe Carpum e poi continua a cercare.)