2013-04-22 19 views
10

Sto provando ad applicare alcune patch al mio repository e ricevere il messaggio patch does not apply a meno che non specifichi i parametri --ignore-space-change --ignore-whitespace. Alcune patch non possono essere applicate anche con questi tasti, dice che ci sono conflitti da risolvere manualmente. (ma in realtà non vi sono conflitti, l'unione automatica deve averlo risolto)Problemi con git format-patch/am (patch non applicabile)

Ho fatto un esperimento: creato una patch da un commit nel mio repository, reimpostato il master sul commit precedente, provato ad applicare patch dal file. Lo stesso messaggio di errore.

Qualche idea, perché questo potrebbe accadere?

UPD i comandi sono molto semplici:

git format-patch -o ../_patches 0f3bf7874c32b22256ae2d9dc00b1afd6464e43c 
git reset --hard 0f3bf7874c32b22256ae2d9dc00b1afd6464e43c 
git am ../_patches/0001-test2.patch 

(id questo si riferisce al primo commit penultimo)

+0

Puoi mostrarci di più su quali comandi stai eseguendo? Su quale sistema operativo stai funzionando? Qual è il contenuto di .gitattributes? – jszakmeister

risposta

2

Aha! Sembra che abbia trovato la ragione. Il repository utilizza terminazioni di riga CRLF, ma format-patch crea file di patch con LF. Quando creo un repository da zero con autocrlf = false e faccio lo stesso esperimento, ho lo stesso problema. (sembra un bug in Git)
Qualche consiglio su come risolvere questo problema?

UPD la mia soluzione era di creare un nuovo repository con autocrlf = true e reimportare tutte le modifiche da entrambi i repository in esso.

9

È necessario passare la flag --keep-cr a git am. È spiacevole, ma a causa degli standard concorrenti (flusso di lavoro della posta elettronica rispetto al locale), non c'è davvero molta scelta.

Si consiglia di provare anche la creazione di un file .gitattributes. Cercando di ricreare il tuo problema, sono riuscito a far funzionare le cose quando ho specificato che il file richiedeva CRLF. Nota, senza prima normalizzare i file, ha mostrato l'intero file come modificato. Io uso un comunemente .gitattributes con questo:

.gitattributes export-ignore 
.gitignore  export-ignore 

*.txt   text 
*.C    text trailing-space space-before-tab -indent-with-non-tab 
*.rst   text trailing-space space-before-tab -indent-with-non-tab 
*.clj   text trailing-space space-before-tab -indent-with-non-tab 

*.c    text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.cpp   text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.h    text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.hpp   text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.py   text diff=python trailing-space space-before-tab -indent-with-non-tab 
*.tex   text diff=tex 
*.java   text diff=java trailing-space space-before-tab -indent-with-non-tab 
*.pl   text diff=perl trailing-space space-before-tab -indent-with-non-tab 
*.php   text diff=php 
*.rb   text diff=ruby trailing-space space-before-tab -indent-with-non-tab 

*.vcproj  eol=crlf 
*.dsp   eol=crlf 
*.dsw   eol=crlf 

*.sh   eol=lf 

*.jpg   binary 
*.png   binary 
*.gif   binary 
*.tiff   binary 

Avrai voglia di normalizzare la vostra linea che termina secondo il gitattributes man page. Un altro utente SO ha finito per disattivare core.autocrlf as well per ottenere commit e patch puliti.

cercando di riprodurre il bug

$ git init repo 
Initialized empty Git repository in c:/tmp/git-eol/repo/.git/ 
$ cd repo 
$ git config --local core.autocrlf false 
$ vim foo.txt 
$ git add foo.txt 
$ git commit -m "Add foo." 
[master (root-commit) 3903abd] Add foo. 
1 file changed, 3 insertions(+) 
create mode 100644 foo.txt 
$ vim foo.txt 
$ git st 
## master 
M foo.txt 
$ git commit -m "Add more foo." -a 
[master 03e991a] Add more foo. 
1 file changed, 2 insertions(+) 
$ git format-patch HEAD~1 
0001-Add-more-foo.patch 
$ vim 0001-Add-more-foo.patch 

Guardando il file di patch che è stato prodotto, vedo questo:

Come si può vedere, i ritorni a capo (^M s) sono stati tenuti nella patch. Questo è con core.autocrlf=false. Proseguendo, vedo:

$ git reset --hard HEAD~1 
HEAD is now at 3903abd Add foo. 
$ git am 0001-Add-more-foo.patch 
Applying: Add more foo. 
error: patch failed: foo.txt:1 
error: foo.txt: patch does not apply 
Patch failed at 0001 Add more foo. 
The copy of the patch that failed is found in: 
    c:/tmp/git-eol/repo/.git/rebase-apply/patch 
When you have resolved this problem, run "git am --resolved". 
If you prefer to skip this patch, run "git am --skip" instead. 
To restore the original branch and stop patching, run "git am --abort". 
$ git am --abort 

Quindi la patch non si applica bene out-of-the-box. L'utilizzo di --keep-cr era come previsto:

$ git am --keep-cr 0001-Add-more-foo.patch 
Applying: Add more foo. 
$ 

OK.Così proviamo questo con core.autocrlf=true (in un repository diverso):

# Removed the initial commands... 
$ git format-patch HEAD~1 
0001-Add-more-foo.patch 
$ git reset --hard HEAD~1 
HEAD is now at 525b5aa Initial commit. 
$ git am 0001-Add-more-foo.patch 
Applying: Add more foo. 
$ git config --get core.autocrlf 
true 

La patch in questo caso ha avuto terminazioni LF ovunque.

+0

Questo non sembra risolvere il problema con patch non applicabili. – fithu

+0

Hai provato? Non solo ho incontrato prima questo problema, ma l'ho riprodotto qui. Sei il commento qui sotto sulla produzione di patch con LF credo non sia corretto. L'intestazione ha LF, ma le linee effettive del diff hanno probabilmente terminazioni CRLF. 'git am' rimuove il CR, che è il punto in cui entra in gioco il problema. Forse hai effettivamente terminazioni di linea * miste *? – jszakmeister

+0

Stai cercando di dirmi che ho torto di avere solo _ assunzioni e credenze_ ?? Non ci sono terminazioni di linee miste. Tutte le terminazioni di riga nei file di patch generati sono LF puri, nonostante il repo utilizzi solo CRLF. – fithu

Problemi correlati