Come modificare un commit specificato?


2233

Di solito invio un elenco di commit per la revisione. Se ho i seguenti commit:

  1. HEAD
  2. Commit3
  3. Commit2
  4. Commit1

... So che posso modificare head commit con git commit --amend. Ma come posso modificare Commit1, dato che non è il HEADcommit?


31
Vedi una risposta alternativa qui: stackoverflow.com/a/18150592/520567 La tua risposta accettata è davvero una risposta esatta alla tua domanda, ma se hai il tuo nuovo commit pronto prima di decidere di usare edit, allora questa risposta sarebbe più semplice. Può anche funzionare con più commit che vuoi unire / schiacciare con uno più vecchio.
Akostadinov

6
Puoi anche vedere Dividere un commit in Git Tools - Riscrivere la cronologia per ulteriori informazioni.
hakre,

Risposte:


2956

Puoi usare git rebase . Ad esempio, se si desidera modificare il commit bbc643cd, eseguire

$ git rebase --interactive 'bbc643cd^'

Si prega di notare il punto di inserimento ^alla fine del comando, poiché è necessario tornare a commit prima di quello che si desidera modificare .

Nel editor predefinito, modificare picka editnella linea di nota 'bbc643cd'.

Salvare il file ed uscire: git interpreterà ed eseguirà automaticamente i comandi nel file. Ti ritroverai nella situazione precedente in cui hai appena creato il commit bbc643cd.

A questo punto, bbc643cdè il tuo ultimo commit e puoi facilmente modificarlo : apporta le tue modifiche e poi commettile con il comando:

$ git commit --all --amend --no-edit

Successivamente, digita:

$ git rebase --continue

per tornare al precedente commit HEAD.

ATTENZIONE : Nota che questo cambierà lo SHA-1 di quel commit così come tutti i bambini - in altre parole, riscrive la storia da quel punto in avanti. È possibile interrompere i repository in questo modo se si preme usando il comandogit push --force


125
Un'altra opzione interessante all'interno di questo flusso è una volta che sei passato al commit che vuoi modificare, invece di modificare i file e ammucchiato sul commit in cima (quello che stai modificando), potresti voler dividere quel commit in due diversi commit (o anche di più). In tal caso, tornare al commit per modificarlo ed eseguire "git reset HEAD ^". che metterà in scena i file modificati di quel commit. Ora seleziona e esegui il commit di tutti i file come desideri. Questo flusso è abbastanza ben spiegato nella pagina man di "git-rebase". Vedi la sezione "Suddivisione dei commit". bit.ly/d50w1M
Diego Pino

200
In Git 1.6.6 e versioni successive è possibile utilizzare l' rewordazione in git rebase -iinvece di edit(apre automaticamente l'editor e continua con il resto dei passaggi di rebase; questo evita l'uso di git commit --ammende git rebase --continuequando è necessario modificare solo il messaggio di commit e non il contenuto ).
Chris Johnsen,

108
Vale la pena notare che potrebbe essere necessario eseguire git stashprima git rebasee git stash popdopo, in caso di modifiche in sospeso.
user123444555621

3
Esiste un comando di scelta rapida per modificare un commit specifico nel rebase interattivo senza aprire l'editor, trovare il commit, contrassegnarlo come modifica e quindi tornare alla riga di comando?
sabato

15
Nota che con Git più recente, sarebbe più saggio seguire le istruzioni rapide invece di usare ciecamente git commit --all --amend --no-editqui. Tutto quello che dovevo fare dopo git rebase -i ...era git commit --amendnormalmente allora git rebase --continue.
Eric Chen,

453

Usa il fantastico rebase interattivo:

git rebase -i @~9   # Show the last 9 commits in a text editor

Trova il commit desiderato, modifica pickin e( edit), salva e chiudi il file. Git tornerà indietro a quel commit, permettendoti di:

  • uso git commit --amend per apportare modifiche o
  • utilizzare git reset @~per scartare l'ultimo commit, ma non le modifiche ai file (ovvero portarti al punto in cui ti trovavi quando avevi modificato i file, ma non hai ancora eseguito il commit).

Quest'ultimo è utile per fare cose più complesse come la suddivisione in più commit.

Quindi, esegui git rebase --continuee Git riprodurrà le modifiche successive in aggiunta al commit modificato. È possibile che ti venga chiesto di correggere alcuni conflitti di unione.

Nota: @è una scorciatoia per HEADed ~è il commit prima del commit specificato.

Maggiori informazioni sulla riscrittura della cronologia nei documenti Git.


Non aver paura di rifare

ProTip ™: non aver paura di sperimentare comandi "pericolosi" che riscrivono la cronologia * - Git non cancella i tuoi commit per 90 giorni di default; li puoi trovare nel reflog:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Fai attenzione a opzioni come --harde --forcesebbene: possono scartare i dati.
* Inoltre, non riscrivere la cronologia su nessun ramo su cui stai collaborando.



Su molti sistemi, git rebase -iaprirà Vim per impostazione predefinita. Vim non funziona come la maggior parte degli editor di testo moderni, quindi dai un'occhiata a come riutilizzare Vim . Se preferisci utilizzare un editor diverso, modificalo con git config --global core.editor your-favorite-text-editor.


29
Il mezzo della tua risposta è un posto strano per mettere quello che posso solo descrivere come un annuncio in miniatura per VIM. È irrilevante per la domanda e ingombra la tua risposta.
Intenti

21
@Intentss: Ah, posso vedere perché sembrava strano. Il ragionamento alla base era che Vim è l'editor di testo predefinito su molti sistemi, quindi la prima esperienza di rebasing interattivo di molte persone è una schermata in cui la digitazione fa girare il cursore ovunque. Quindi, cambiano il loro editor in qualcos'altro e la loro seconda esperienza di rebasing interattivo è abbastanza normale, ma li lascia chiedersi perché utilizza un file di testo anziché una GUI. Per raggiungere il flusso con il rebasing, hai bisogno di qualcosa come Vim o la modalità rebase di Emacs.
Zaz,

9
Va bene. Visto che così tante persone trovano irrilevante quella parte, l'ho ridotta in 3 righe e ho anche spiegato come modificare l'editor se necessario.
Zaz,

17
Eccezionale! Non sapevo che potessi usare @come stenografia per HEAD. Grazie per aver pubblicato questo
James Ko,

3
git reset @~esattamente quello che volevo fare dopo aver scelto commit with git rebase .... Sei il mio eroe)
18

79

Rifacimento interattivo con--autosquash è qualcosa che uso frequentemente quando ho bisogno di sistemare i commit precedenti più in profondità nella storia. In sostanza, accelera il processo illustrato dalla risposta di ZelluX ed è particolarmente utile quando hai più di un commit che devi modificare.

Dalla documentazione:

--autosquash

Quando il messaggio di registro di commit inizia con "squash! ..." (o "fixup! ...") e c'è un commit il cui titolo inizia con lo stesso ..., modifica automaticamente la todo list di rebase -i in modo che il commit contrassegnato per la compressione viene subito dopo la modifica del commit

Supponiamo di avere una storia simile a questa:

$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1

e hai delle modifiche che desideri modificare in Commit2, quindi esegui il commit delle modifiche utilizzando

$ git commit -m "fixup! Commit2"

in alternativa puoi usare commit-sha invece del messaggio di commit, quindi "fixup! e8adec4 o anche solo un prefisso del messaggio di commit.

Quindi avviare un rebase interattivo sul commit prima

$ git rebase e8adec4^ -i --autosquash

il tuo editor si aprirà con i commit già correttamente ordinati

pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3

tutto ciò che devi fare è salvare ed uscire


21
Puoi anche usare al git commit --fixup=@~posto di git commit -m "fixup! Commit2". Ciò è particolarmente utile quando i tuoi messaggi di commit sono più lunghi e sarebbe una seccatura scrivere tutto.
Zaz,

42

Correre:

$ git rebase --interactive commit_hash^

ognuno ^indica quanti commit si desidera modificare, se è solo uno (l'hash di commit specificato), quindi basta aggiungerne uno ^.

Con Vim puoi cambiare le parole pickin rewordper i commit che vuoi cambiare, salvare ed uscire (:wq ). Quindi git ti chiederà ogni commit che hai contrassegnato come reword in modo da poter cambiare il messaggio di commit.

Ogni messaggio di commit è necessario salvare ed uscire ( :wq) per passare al messaggio di commit successivo

Se si desidera uscire senza applicare le modifiche, premere :q!

MODIFICA : per navigare in vimte usa jper salire, kper scendere, hper andare a sinistra e lper andare a destra (tutto questo in NORMALmodalità, premi ESCper passare alla NORMALmodalità). Per modificare un testo, premere in imodo da accedere alla INSERTmodalità in cui inserire il testo. Premere ESCper tornare alla NORMALmodalità :)

AGGIORNAMENTO : Ecco un ottimo link dalla lista di github Come annullare (quasi) qualsiasi cosa con git


4
Ha funzionato perfettamente per me. Vale la pena menzionare git push --force?
u01jmg3,

Quello che git push --forcefa è sovrascrivere i commit dei telecomandi con i tuoi commit locali. Questo non è il caso di questo argomento :)
betoharres

@BetuUuUu, naturalmente, se i tuoi commit sono trasferiti a remoto e hai modificato il messaggio di commit localmente, vorresti forzare il push a remoto, non è vero?
Sudip Bhandari,

@SudipBhandari Questa è la sensazione che provo. Non ho forzato, e ora ho un ramo in più, rispecchiando tutti i commit su quello di cui ho cambiato il messaggio, il che è super brutto.
ruffin,

2
@greenhouse se modifichi e spingi forzatamente, molto probabilmente altri membri del team incontreranno conflitti di fusione. Quindi dovresti essere generalmente molto cauto al riguardo. Ma se modifichi qualcosa che nessun altro ha ancora recuperato, dovrebbe andare bene (non lo noterai). Quindi considererei - force come ultima risorsa e consulti sempre lo stato del repository con altri membri.
Tomasz Kaczmarzyk,

18

Se per qualche motivo non ti piacciono gli editor interattivi, puoi usarli git rebase --onto.

Di 'che vuoi modificare Commit1. In primo luogo, ramo da prima Commit1 :

git checkout -b amending [commit before Commit1]

Secondo, prendi Commit1con cherry-pick:

git cherry-pick Commit1

Ora modifica le modifiche, creando Commit1':

git add ...
git commit --amend -m "new message for Commit1"

E infine, dopo aver nascosto tutte le altre modifiche, trapianta il resto dei tuoi commit fino a completare masteril nuovo commit:

git rebase --onto amending Commit1 master

Leggi: "rebase, sul ramo amending, tutto si impegna tra Commit1(non inclusivo) e master(compreso)". Cioè, Commit2 e Commit3, eliminando completamente il vecchio Commit1. Potresti semplicemente selezionarli, ma in questo modo è più facile.

Ricorda di ripulire i tuoi rami!

git branch -d amending

4
puoi usare git checkout -b amending Commit1~1per ottenere il commit precedente
Arin Taylor,

I primi due passaggi sono equivalenti a git checkout -b amending Commit1?
Haoshu,

16

Basato sulla documentazione

Modifica del messaggio di messaggi di commit più vecchi o multipli

git rebase -i HEAD~3 

Quanto sopra mostra un elenco degli ultimi 3 commit sul ramo corrente, cambia 3 in qualcos'altro se vuoi di più. L'elenco sarà simile al seguente:

pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Sostituisci pick con reword prima di ogni messaggio di commit che desideri modificare. Supponiamo che tu modifichi il secondo commit nell'elenco, il tuo file sarà simile al seguente:

pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Salvare e chiudere il file dell'elenco di commit, verrà visualizzato un nuovo editor per modificare il messaggio di commit, modificare il messaggio di commit e salvare.

Finaly Forza-spingi gli commit modificati.

git push --force

Ottengo il seguente errore: errore: si è verificato un problema con l'editor "vi". Fornisci il messaggio usando l'opzione -m o -F.
Erick Maynard,

12

Comando completamente non interattivo (1)

Ho pensato di condividere un alias che sto usando per questo. Si basa su rebase interattivo non interattivo. Per aggiungerlo a Git, eseguire questo comando (spiegazione fornita di seguito):

git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"; }; f'

Il più grande vantaggio di questo comando è il fatto che è no-vim .


(1) dato che non ci sono conflitti durante il rebase, ovviamente

uso

git amend-to <REV> # e.g.
git amend-to HEAD~1
git amend-to aaaa1111

Il nome amend-tosembra appropriato IMHO. Confronta il flusso con --amend:

git add . && git commit --amend --no-edit
# vs
git add . && git amend-to <REV>

Spiegazione

  • git config --global alias.<NAME> '!<COMMAND>'- crea un alias git globale denominato <NAME>che eseguirà il comando non git<COMMAND>
  • f() { <BODY> }; f - una funzione bash "anonima".
  • SHA=`git rev-parse "$1"`; - converte l'argomento in git revision e assegna il risultato a variabile SHA
  • git commit --fixup "$SHA"- fixup-commit per SHA. Vedi git-commitdocumenti
  • GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"
    • git rebase --interactive "$SHA^" la parte è stata coperta da altre risposte.
    • --autosquashè ciò che viene utilizzato insieme a git commit --fixup, vedere git-rebasedocumenti per ulteriori informazioni
    • GIT_SEQUENCE_EDITOR=trueè ciò che rende il tutto non interattivo. Questo trucco che ho imparato da questo post sul blog .

1
Si può anche fare in modo che amend-togestisca i file non messi in scena: git config --global alias.amend-to '!f() { SHA=git rev-parse "$ 1"; git stash -k && git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^" && git stash pop; }; f'
Dethariel

2
Una preoccupazione con questo metodo è che potrebbe applicare correzioni non correlate.
Ciro Santilli 3 冠状 病 六四 事件 法轮功

Il punto della domanda non è cambiare il messaggio di commit? Perché questa risposta non si rivolge a questo, o almeno non direttamente.
wytten,

@wytten la domanda non si pone sulla modifica del messaggio di commit, si tratta di modificare il commit non è HEAD. Quindi una risposta alla tua domanda sarebbe "no, non è il punto della domanda"
Dethariel,

Sono confuso, quindi come possiamo modificare il messaggio di commit?
ggb667,

8

Modifica del rebase interattivo automatizzata seguita da commit revert pronto per un do-over

Mi sono ritrovato a correggere un impegno passato abbastanza frequentemente da aver scritto una sceneggiatura per questo.

Ecco il flusso di lavoro:

  1. git commit-edit <commit-hash>
    

    Questo ti lascerà al commit che vuoi modificare.

  2. Correggi e metti in scena il commit come vorresti fosse stato in primo luogo.

    (Potresti voler usare git stash saveper conservare tutti i file che non stai commettendo)

  3. Ripeti il ​​commit con --amend, ad esempio:

    git commit --amend
    
  4. Completa il rebase:

    git rebase --continue
    

Affinché quanto sopra funzioni, inserisci lo script seguente in un file eseguibile chiamato git-commit-editda qualche parte nel tuo $PATH:

#!/bin/bash

set -euo pipefail

script_name=${0##*/}

warn () { printf '%s: %s\n' "$script_name" "$*" >&2; }
die () { warn "$@"; exit 1; }

[[ $# -ge 2 ]] && die "Expected single commit to edit. Defaults to HEAD~"

# Default to editing the parent of the most recent commit
# The most recent commit can be edited with `git commit --amend`
commit=$(git rev-parse --short "${1:-HEAD~}")
message=$(git log -1 --format='%h %s' "$commit")

if [[ $OSTYPE =~ ^darwin ]]; then
  sed_inplace=(sed -Ei "")
else
  sed_inplace=(sed -Ei)
fi

export GIT_SEQUENCE_EDITOR="${sed_inplace[*]} "' "s/^pick ('"$commit"' .*)/edit \\1/"'
git rebase --quiet --interactive --autostash --autosquash "$commit"~
git reset --quiet @~ "$(git rev-parse --show-toplevel)"  # Reset the cache of the toplevel directory to the previous commit
git commit --quiet --amend --no-edit --allow-empty  #  Commit an empty commit so that that cache diffs are un-reversed

echo
echo "Editing commit: $message" >&2
echo

7

È venuto a questo approccio (ed è probabilmente esattamente lo stesso che usare il rebase interattivo) ma per me è un po 'semplice.

Nota: vi presento questo approccio a scopo illustrativo di ciò che potete fare piuttosto che un'alternativa quotidiana. Dal momento che ha molti passaggi (e forse alcuni avvertimenti).

Supponi di voler modificare il commit 0e che sei attualmente attivofeature-branch

some-commit---0---1---2---(feature-branch)HEAD

Vai a questo commit e crea un quick-branch. È inoltre possibile clonare il ramo della funzione come punto di ripristino (prima di iniziare).

?(git checkout -b feature-branch-backup)
git checkout 0
git checkout -b quick-branch

Ora avrai qualcosa del genere:

0(quick-branch)HEAD---1---2---(feature-branch)

Cambiamenti di scena, metti tutto il resto.

git add ./example.txt
git stash

Salva le modifiche e torna a feature-branch

git commit --amend
git checkout feature-branch

Ora avrai qualcosa del genere:

some-commit---0---1---2---(feature-branch)HEAD
           \
             ---0'(quick-branch)

Rebase feature-branchsu quick-branch(risolvi eventuali conflitti lungo il percorso). Applicare stash e rimuovere quick-branch.

git rebase quick-branch
git stash pop
git branch -D quick-branch

E finisci con:

some-commit---0'---1'---2'---HEAD(feature-branch)

Git non duplicherà (anche se non posso davvero dire fino a che punto) lo 0 commette durante il rebasing.

Nota: tutti gli hash di commit vengono modificati a partire dal commit che inizialmente intendevamo modificare.


6

Per ottenere un comando non interattivo, inserisci uno script con questo contenuto nel PERCORSO:

#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"

Usalo mettendo in scena le modifiche (con git add) e quindi esegui git fixup <commit-to-modify>. Naturalmente, sarà comunque interattivo se si verificano conflitti.


1
Funziona bene Ho aggiunto alcune funzionalità extra per eseguire correzioni frammentarie di un albero sporco per perfezionare un set di commit. `dirtydiff = $ (git diff); if ["$ {dirtydiff}"! = ""]; quindi echo "Riporre l'albero sporco"> & 2; git stash; fi;
Simon Feltman,

6

git stash+ rebaseautomazione

Per quando ho bisogno di modificare un vecchio commit molte volte per le recensioni di Gerrit, ho fatto:

git-amend-old() (
  # Stash, apply to past commit, and rebase the current branch on to of the result.
  current_branch="$(git rev-parse --abbrev-ref HEAD)"
  apply_to="$1"
  git stash
  git checkout "$apply_to"
  git stash apply
  git add -u
  git commit --amend --no-edit
  new_sha="$(git log --format="%H" -n 1)"
  git checkout "$current_branch"
  git rebase --onto "$new_sha" "$apply_to"
)

GitHub a monte .

Uso:

  • modificare il file di origine, non è necessario git addse già in repository
  • git-amend-old $old_sha

Mi piace questo in --autosquashquanto non schiaccia altre correzioni non correlate.


Soluzione molto bella, questa dovrebbe essere un'opzione predefinita git amendper applicare le modifiche a un commit specifico con l'utilizzo della scorta corrente, molto intelligente!
caiohamamura,

5

Ho risolto questo

1) creando un nuovo commit con le modifiche che voglio ..

r8gs4r commit 0

2) So quale impegno devo unirmi a esso. che è commit 3.

quindi, git rebase -i HEAD~4# 4 rappresenta il recente commit 4 (qui il commit 3 è al 4 ° posto)

3) in rebase interattivo il recente commit si troverà in fondo. sarà simile,

pick q6ade6 commit 3
pick vr43de commit 2
pick ac123d commit 1
pick r8gs4r commit 0

4) qui è necessario riorganizzare il commit se si desidera unire uno specifico. dovrebbe essere come

parent
|_child

pick q6ade6 commit 3
f r8gs4r commit 0
pick vr43de commit 2
pick ac123d commit 1

dopo riorganizzare è necessario sostituire p pickcon f( fixup si unirà senza messaggio di commit) o s( squash merge con il messaggio di commit può cambiare in fase di esecuzione)

e poi salva il tuo albero.

ora unione completata con commit esistente.

Nota: il suo metodo non è preferibile a meno che tu non lo mantenga da solo. se hai una grande squadra non è un metodo accettabile per riscrivere git tree finirà in conflitti che non conosci. se vuoi mantenere l'albero pulito con meno commit puoi provare questo e se la sua piccola squadra non è preferibile .....


Questa è una buona soluzione se non si desidera apportare modifiche live durante un rebase interattivo.
Dunatotatos,

4

L'opzione migliore è utilizzare "Comando rebase interattivo" .

Il git rebasecomando è incredibilmente potente. Ti consente di modificare i messaggi di commit , combinare i commit, riordinarli ... ecc.

Ogni volta che si ribadisce un commit, verrà creato un nuovo SHA per ciascun commit, indipendentemente dal fatto che il contenuto venga modificato o meno! Dovresti stare attento quando usare questo comando perché potrebbe avere conseguenze drastiche soprattutto se lavori in collaborazione con altri sviluppatori. Potrebbero iniziare a lavorare con il tuo commit mentre ne stai riformulando un po '. Dopo aver forzato a spingere i commit saranno fuori sincrono e potresti scoprirlo in seguito in una situazione disordinata. Quindi sii attento!

Si consiglia di creare una backupsuccursale prima di effettuare la rebasing, quindi ogni volta che si trovano cose fuori controllo è possibile tornare allo stato precedente.

Ora come usare questo comando?

git rebase -i <base> 

-iindicare "interattivo" . Si noti che è possibile eseguire un rebase in modalità non interattiva. ex:

#interactivly rebase the n commits from the current position, n is a given number(2,3 ...etc)
git rebase -i HEAD~n 

HEADindica la posizione corrente (può anche essere il nome della filiale o il commit SHA). Il ~nmezzo "n beforeé, così HEAD~nsarà la lista di 'n' commit prima di quello che si sta attualmente.

git rebase ha un comando diverso come:

  • po pickcontinuare a impegnarsi così com'è.
  • roppure reword: per mantenere il contenuto del commit ma modificare il messaggio di commit.
  • soppure squash: per combinare le modifiche di questo commit nel commit precedente (il commit sopra di esso nell'elenco).
  • ... eccetera.

    Nota: è meglio far funzionare Git con l'editor di codice per semplificare le cose. Ad esempio, se si utilizza il codice visivo, è possibile aggiungere in questo modo git config --global core.editor "code --wait". Oppure puoi cercare in Google come associare il tuo editor di codice preferito a GIT.

Esempio di git rebase

Volevo cambiare gli ultimi 2 commit che ho fatto, quindi ho elaborato in questo modo:

  1. Visualizza i commit correnti:
    #This to show all the commits on one line
    $git log --oneline
    4f3d0c8 (HEAD -> documentation) docs: Add project description and included files"
    4d95e08 docs: Add created date and project title"
    eaf7978 (origin/master , origin/HEAD, master) Inital commit
    46a5819 Create README.md
    
  2. Ora uso git rebaseper modificare gli ultimi 2 messaggi di commit: $git rebase -i HEAD~2 apre l'editor di codice e mostra questo:

    pick 4d95e08 docs: Add created date and project title
    pick 4f3d0c8 docs: Add project description and included files
    
    # Rebase eaf7978..4f3d0c8 onto eaf7978 (2 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    ...
    

    Dal momento che voglio cambiare il messaggio di commit per questo 2 commit. Quindi scriverò ro rewordal posto di pick. Quindi salvare il file e chiudere la scheda. Si noti che rebaseviene eseguito in un processo in più passaggi, quindi il passaggio successivo è aggiornare i messaggi. Si noti inoltre che i commit vengono visualizzati in ordine cronologico inverso, quindi l'ultimo commit viene visualizzato in quello e il primo commit nella prima riga e così via.

  3. Aggiorna i messaggi: aggiorna il primo messaggio:

    docs: Add created date and project title to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    salva e chiudi Modifica il secondo messaggio

    docs: Add project description and included files to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    salva e chiudi.

  4. Riceverai un messaggio come questo entro la fine del rebase: il Successfully rebased and updated refs/heads/documentationche significa che hai successo. È possibile visualizzare le modifiche:

    5dff827 (HEAD -> documentation) docs: Add project description and included files to the documentation "README.md"
    4585c68 docs: Add created date and project title to the documentation "README.md"
    eaf7978 (origin/master, origin/HEAD, master) Inital commit
    46a5819 Create README.md
    

    Vorrei che ciò potesse aiutare i nuovi utenti :).


2

Per me è stato per rimuovere alcune credenziali da un repository. Ho provato a riformare e ho incontrato un sacco di conflitti apparentemente non correlati lungo la strada quando provavo a ribattere: continuare. Non preoccuparti di tentare di rifare te stesso, usa lo strumento chiamato BFG (brew install bfg) su mac.


0

Se non hai già eseguito il push dei commit, puoi tornare a un commit precedente usando git reset HEAD^[1,2,3,4...]

Per esempio

git commit <file1> -m "Updated files 1 and 2"
git commit <file3> -m "Updated file 3"

Spiacenti, ho dimenticato di aggiungere file2 al primo commit ...

git reset HEAD^1 // because I only need to go back 1 commit

git add <file2>

Ciò aggiungerà file2 al primo commit.


0

Bene, questa soluzione potrebbe sembrare molto sciocca, ma può salvarti in determinate condizioni.

Un mio amico si è appena imbattuto accidentalmente in alcuni file enormi (quattro file generati automaticamente che vanno da 3 GB a 5 GB ciascuno) e poi ha fatto alcuni commit di codice aggiuntivo prima di rendersi conto del problema che git pushnon funzionava più!

I file erano stati elencati .gitignorema dopo aver rinominato la cartella del contenitore, sono stati esposti e impegnati! E ora c'erano ancora alcuni commit del codice, ma pushfunzionava per sempre (cercando di caricare GB di dati!) E alla fine falliva a causa dei limiti di dimensione del file di Github .

Il problema con rebase interattivo o qualcosa di simile era che avrebbero avuto a che fare con la ricerca di questi file enormi e che avrebbero impiegato un'eternità a fare qualsiasi cosa. Tuttavia, dopo aver trascorso quasi un'ora nella CLI, non eravamo sicuri che i file (e i delta) fossero effettivamente rimossi dalla cronologia o semplicemente non inclusi negli commit correnti. Neanche la spinta funzionava e il mio amico era davvero bloccato.

Quindi, la soluzione che ho trovato è stata:

  1. Rinomina la cartella git corrente in ~/Project-old .
  2. Clona nuovamente la cartella git da github (a ~/Project ).
  3. Acquista nello stesso ramo.
  4. Manualmente cp -ri file dalla ~/Project-oldcartella a~/Project .
  5. Assicurati che i file di grandi dimensioni, che non sono necessari per il check-in, siano modificati mve inclusi.gitignore correttamente.
  6. Assicurati anche di non sovrascrivere la .gitcartella nella clonata di recente~/Project di da quella precedente. Ecco dove vivono i registri della storia problematica!
  7. Ora rivedi le modifiche. Dovrebbe essere l'unione di tutti i commit recenti, esclusi i file problematici.
  8. Infine, esegui il commit delle modifiche ed è bene essere push"redatte".

Il problema più grande con questa soluzione è che si occupa della copia manuale di alcuni file e unisce tutti i recenti commit in uno (ovviamente con un nuovo commit-hash.) B

I grandi vantaggi sono che, è molto chiaro in ogni fase, funziona benissimo per file di grandi dimensioni (oltre a quelli sensibili) e non lascia alcuna traccia nella storia!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.