Aggiungi tutti i file a un commit tranne un singolo file?


571

Ho un sacco di file in un changeset, ma voglio ignorare specificamente un singolo file modificato. Sembra così dopo git status:

# modified:   main/dontcheckmein.txt
# deleted:    main/plzcheckmein.c
# deleted:    main/plzcheckmein2.c
...

C'è un modo in cui posso fare git addma ignorare solo un file di testo che non voglio toccare? Qualcosa di simile a:

git add -u -except main/dontcheckmein.txt

Risposte:


851
git add -u
git reset -- main/dontcheckmein.txt

28
come escludo l'intera cartella? - principale o principale / o principale / *?
Alan Coromano,

8
@MariusKavansky Puoi usare tutti questi moduli. Se lo usi main/*è necessario aggiungerlo --di fronte per far sapere a Git che si tratta di un percorso. Le altre due varianti funzionano senza includere i due trattini. (Testato nel prompt dei comandi su Windows 7 con msysGit)
dennisschagt

2
Se hai alcune cartelle che vuoi escludere che contengono un'enorme quantità di file o altre cartelle: aggiungile temporaneamente a gitignore. l'esecuzione di una git resetper quelle cartelle in seguito funzionerà ancora, ma ci vorrà molto tempo per aggiungere le cartelle di grandi dimensioni.
Michael Trouw,

2
Quindi, non c'è una linea?
BroVic,

5
@Ben Jackson sarebbe bello commentare ogni riga, non credi?
ed1nh0

140

1) Per iniziare a ignorare le modifiche a un singolo file già con versione

git update-index --assume-unchanged "main/dontcheckmein.txt"

e per annullarlo git update-index --no-assume-unchanged "main/dontcheckmein.txt"

documenti github per ignorare i file

2) Ignorare completamente un singolo file specifico impedendone la creazione nel repository

Per prima cosa, guarda questo post di StackOverflow: Git Global Ignore non funziona

In .gitignore, aggiungi il percorso relativo al file senza lead ./.

Quindi, se il tuo file è MyProject/MyFolder/myfile.txt, (dove si .gittrova anche nella MyProjectcartella), aggiungi MyFolder/myfile.txtal tuo .gitignorefile.

Puoi confermare quali regole sono associate a ignora tramite git check-ignore "MyFolder/myfile.txt"

A proposito di globale ignorare

Quel link parla ~/.gitignore_global, ma il file è legato al tuo progetto. Quindi, se si mette il modello esclude MyFolder/myfile.txtin ~/.gitignore_global, funzionerà, ma non ha molto senso ...

D'altra parte, se si imposta il progetto con git config core.excludesfile .gitignoredove si .gitignoretrova MyProject, il file locale avrà la precedenza ~/.gitignore_global, il che può avere regole molto utili ...

Quindi, per ora, penso che sia meglio fare qualche script per mescolare il vostro .gitignorecon ~/.gitignore_globala .gitignore.

Un ultimo avvertimento
Se il file che si desidera ignorare è già nel repository, questo metodo non funzionerà a meno che non si esegua questa operazione: git rm "MyFolder/myfile.txt"ma prima eseguirne il backup, poiché verrà rimosso anche localmente! Puoi copiarlo più tardi ...


5
È possibile utilizzare git rm --cached MyFolder/myyfile.txtper rimuovere il file dal repository ma conservarlo localmente. Spiegazione su help.github.com
dennisschagt

87

Per un file

git add -u
git reset -- main/dontcheckmein.txt

Per una cartella

git add -u
git reset -- main/*

9
perché è necessario il -u? perchè no git add . && git reset -- main/*?

2
L'opzione -u aggiorna l'indice nel punto in cui ha già una voce corrispondente a <pathspec>. Ciò rimuove e modifica le voci dell'indice in modo che corrispondano all'albero di lavoro, ma non aggiunge nuovi file. Se non viene specificato <pathspec> quando viene utilizzata l'opzione -u, vengono aggiornati tutti i file tracciati nell'intero albero di lavoro (le vecchie versioni di Git venivano utilizzate per limitare l'aggiornamento alla directory corrente e alle sue sottodirectory).
Farhad Mammadli,

6
Qualcuno può spiegare perché il -u è necessario in un linguaggio comprensibile ai professionisti non git?
Patrick,

2
-u viene utilizzato per fare riferimento al ramo in cui stai spingendo. Non dovrai più digitare il git push origin mastertuo prossimo push, solo git pushe git saprà che è nel ramo master. Spero che sia d'aiuto.
Pepeng Hapon,

69

Ora gitsupporta la exclude certain paths and filesmagia pathspec :(exclude)e la sua forma abbreviata :!. Quindi puoi facilmente raggiungerlo come il seguente comando.

git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt

In realtà è possibile specificare di più:

git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*

1
La migliore risposta, grazie! Almeno, per il mio caso: avevo solo bisogno di escludere un tipo di file.
Andre Polykanine,

15
Questo è eccellente! Si noti che su Linux, è necessario citare le :!...clausole per evitare che la shell si lamenti. Così, per esempio: git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'.
Martin_W,

C'è qualcosa come :!/path/to/(file1|file2)?
seeker_of_bacon,

Questo si scontra con qualcosa in zsh, non funziona per me su macOS e git più recenti.
Merlin,

1
Qualcuno può indicare dove questo è ufficialmente documentato?
samurai_jane,

20

Mentre Ben Jackson ha ragione, ho pensato di aggiungere anche come ho usato quella soluzione. Di seguito è riportato uno script molto semplice che uso (che chiamo gitadd) per aggiungere tutte le modifiche tranne alcune selezionate che tengo elencate in un file chiamato .gittrackignore(molto simile a come funziona .gitignore).

#!/bin/bash
set -e

git add -A
git reset `cat .gittrackignore`

E questo è .gittrackignorecome appare la mia corrente .

project.properties

Sto lavorando a un progetto Android che compilo dalla riga di comando durante la distribuzione. Questo progetto dipende da SherlockActionBar, quindi deve essere referenziato in project.properties, ma questo fa confusione con la compilazione, quindi ora scrivo gitadde aggiungo tutte le modifiche a git senza dover annullare l'aggiunta di project.properties ogni volta.


Non sapevo cosa --fosse fino al tuo commento. Secondo le pagine man, è facoltativo e non cambia il risultato del comando (almeno in questo caso). Questa domanda sembra supportarlo, stackoverflow.com/questions/17800994/… . Correggimi se sbaglio, ma sembra che significhi "tratta qualcosa dopo --come argomenti, non opzioni / opzioni"
Anthony Naddeo,

Un buon uso di --in git checkoutvedo in quella domanda. Non sapevo quale fosse il doppio trattino fino a questo nostro scambio. Mi chiedo se l' git checkoutambiguità tra rami e file possa influenzare, anche in questa o in un'altra forma git reset.
Giulio Piancastelli,

10

Per mantenere la modifica nel file ma non per impegnarmi, l'ho fatto

git add .

git reset -- main/dontcheckmein.txt

git commit -m "commit message"

per verificare che il file sia escluso, fare

git status


4

Utilizzare git add -Aper aggiungere contemporaneamente tutti i file modificati e aggiunti di recente.

Esempio

git add -A
git reset -- main/dontcheckmein.txt



1

Per il caso specifico nella domanda, il modo più semplice sarebbe quello di aggiungere tutti i file con estensione .c e tralasciare tutto il resto:

git add *.c

Da git-scm (o / e man git add):

git aggiungi <pathspec> ...

File da cui aggiungere contenuti. Fileglobs (ad es. * .C) possono essere forniti per aggiungere tutti i file corrispondenti. <...>

Nota che questo significa che potresti anche fare qualcosa del tipo:

git add **/main/*

per aggiungere tutti i file (che non vengono ignorati) che si trovano nella maincartella. Puoi persino scatenarti con schemi più elaborati:

git add **/s?c/*Service*

Quanto sopra aggiungerà tutti i file che si trovano nella s(any char)ccartella e hanno Serviceda qualche parte nel loro nome file.

Ovviamente, non sei limitato a un modello per comando. Cioè, potresti chiedere a git di aggiungere tutti i file con estensione .c e .h :

git add *.c *.h

Questo link potrebbe darti qualche idea in più sul modello glob.

Lo trovo particolarmente utile quando sto apportando molti cambiamenti, ma voglio ancora che i miei impegni rimangano atomici e riflettano un processo graduale piuttosto che un miscuglio di cambiamenti che potrei lavorare in quel momento. Ovviamente, ad un certo punto il costo derivante da schemi elaborati supera il costo dell'aggiunta di file con metodi più semplici, o anche di un file alla volta. Tuttavia, la maggior parte delle volte sono facilmente in grado di individuare solo i file di cui ho bisogno con un semplice schema ed escludere tutto il resto.

A proposito, potresti aver bisogno di citare i tuoi schemi glob per farli funzionare, ma non è mai stato così per me.


0

Ne uso git add --patchparecchio e volevo qualcosa del genere per evitare di dover colpire dcontinuamente attraverso gli stessi file. Ho montato un paio di alias git molto confusi per portare a termine il lavoro:

[alias]
    HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
    ap                      = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"

Nel mio caso volevo solo ignorare determinati file minimizzati in ogni momento, ma potevi farlo usare una variabile d'ambiente come $GIT_EXCLUDE_PATTERNper un caso d'uso più generale.


0

Modifiche da impegnare: (utilizzare "git reset HEAD ..." per annullare la fase)


0

Puoi provare questo: git add * && git reset main/dontcheckmein.txt

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.