Tambahkan semua file ke komit kecuali satu file?

571

Saya memiliki banyak file dalam changeset, tetapi saya ingin secara khusus mengabaikan satu file yang dimodifikasi. Terlihat seperti ini setelah git status:

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

Apakah ada cara yang bisa saya lakukan git addtetapi abaikan saja satu file teks yang tidak ingin saya sentuh? Sesuatu seperti:

git add -u -except main/dontcheckmein.txt
pengguna291701
sumber

Jawaban:

851
git add -u
git reset -- main/dontcheckmein.txt
Ben Jackson
sumber
28
bagaimana cara mengecualikan seluruh folder? - main atau main / atau main / *?
Alan Coromano
8
@MariusKavansky Anda dapat menggunakan semua formulir ini. Jika Anda menggunakannya main/*, perlu menambahkan --di depannya untuk memberi tahu git bahwa itu adalah path. Dua varian lainnya berfungsi tanpa menyertakan dua tanda hubung. (Diuji di command prompt pada Windows 7 dengan msysGit)
dennisschagt
2
Jika Anda memiliki beberapa folder yang ingin Anda kecualikan yang berisi banyak file atau folder lain: tambahkan sementara ke gitignore Anda. melakukan a git resetuntuk folder-folder itu sesudahnya masih akan berfungsi, tetapi akan butuh waktu lama untuk menambahkan folder besar.
Michael Trouw
2
Jadi, tidak ada satu kalimat pun?
BroVic
5
@ Ben Jackson akan senang berkomentar setiap baris, bukan begitu?
ed1nh0
140

1) Untuk mulai mengabaikan perubahan pada satu file yang sudah diversi

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

dan untuk membatalkannya git update-index --no-assume-unchanged "main/dontcheckmein.txt"

github docs untuk mengabaikan file

2) Untuk benar-benar mengabaikan satu file tertentu yang mencegahnya dibuat di repositori

Pertama, lihat posting stackoverflow ini: Git global diabaikan tidak berfungsi

Di .gitignore, tambahkan path relatif ke file tanpa memimpin ./.

Jadi, jika file Anda di MyProject/MyFolder/myfile.txt, (di mana .gitjuga di MyProjectfolder), tambahkan MyFolder/myfile.txtke .gitignorefile Anda di .

Anda dapat mengonfirmasi aturan apa yang dikaitkan dengan pengabaian via git check-ignore "MyFolder/myfile.txt"

Tentang pengabaian global

Tautan itu berbicara tentang ~/.gitignore_global, tetapi file tersebut terkait dengan proyek Anda. Jadi, jika Anda meletakkan mengecualikan pola MyFolder/myfile.txtdi ~/.gitignore_global, ia akan bekerja tetapi tidak akan masuk akal ...

Di sisi lain, jika Anda mengatur proyek Anda dengan di git config core.excludesfile .gitignoremana .gitignoreberada MyProject, file lokal akan menimpa ~/.gitignore_global, yang dapat memiliki aturan yang sangat berguna ...

Jadi, untuk saat ini, saya pikir yang terbaik adalah membuat beberapa skrip untuk mencampur .gitignoredengan Anda ~/.gitignore_globaldi .gitignore.

Satu peringatan terakhir
Jika file yang ingin Anda abaikan sudah ada dalam repositori, metode ini tidak akan berfungsi kecuali jika Anda melakukan ini:, git rm "MyFolder/myfile.txt"tetapi cadangkan terlebih dahulu, karena akan dihapus secara lokal juga! Anda dapat menyalinnya kembali nanti ...

Aquarius Power
sumber
5
Anda dapat menggunakan git rm --cached MyFolder/myyfile.txtuntuk menghapus file dari repositori tetapi menyimpannya secara lokal. Penjelasan di help.github.com
dennisschagt
87

Untuk File

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

Untuk folder

git add -u
git reset -- main/*
Rituraj ratan
sumber
9
mengapa -u diperlukan? mengapa tidak git add . && git reset -- main/*?
2
Opsi -u memperbarui indeks di tempat yang sudah memiliki entri yang cocok dengan <pathspec>. Ini menghapus serta memodifikasi entri indeks agar sesuai dengan pohon kerja, tetapi tidak menambahkan file baru. Jika tidak ada <pathspec> yang diberikan ketika opsi -u digunakan, semua file yang dilacak di seluruh pohon kerja diperbarui (Git versi lama digunakan untuk membatasi pembaruan ke direktori saat ini dan subdirektori).
Farhad Mammadli
6
Adakah yang bisa menjelaskan mengapa -u diperlukan dalam bahasa yang dimengerti oleh non-git?
Patrick
2
-u digunakan untuk referensi cabang Anda saat ini Anda mendorong. Anda tidak perlu lagi mengetik git push origin masterdi push berikutnya, adil git pushdan git akan tahu bahwa itu ada di cabang utama. Semoga ini bisa membantu.
Pepeng Hapon
69

Sekarang gitdidukung exclude certain paths and filesoleh pathspec magic :(exclude)dan bentuk pendeknya :!. Jadi Anda dapat dengan mudah mencapainya sebagai perintah berikut.

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

Sebenarnya Anda dapat menentukan lebih banyak:

git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
mata kucing
sumber
1
Jawaban terbaik, terima kasih! Setidaknya, untuk kasus saya: Saya hanya perlu mengecualikan jenis file.
Andre Polykanine
15
Ini luar biasa! Perhatikan bahwa di Linux, Anda perlu mengutip :!...klausa agar shell tidak mengeluh. Jadi, misalnya: git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'.
Martin_W
Apakah ada yang seperti itu :!/path/to/(file1|file2)?
seeker_of_bacon
Ini bertabrakan dengan sesuatu di zsh, tidak berfungsi untuk saya di macOS dan git terbaru.
Merlin
1
Dapatkah seseorang menunjuk ke tempat ini secara resmi didokumentasikan?
samurai_jane
20

Sementara Ben Jackson benar, saya pikir saya akan menambahkan bagaimana saya telah menggunakan solusi itu juga. Di bawah ini adalah skrip yang sangat sederhana yang saya gunakan (yang saya sebut gitadd) untuk menambahkan semua perubahan kecuali beberapa pilihan yang saya simpan dalam file bernama .gittrackignore(sangat mirip dengan cara .gitignore bekerja).

#!/bin/bash
set -e

git add -A
git reset `cat .gittrackignore`

Dan inilah yang .gittrackignoreterlihat seperti saat ini .

project.properties

Saya sedang mengerjakan proyek Android yang saya kompilasi dari baris perintah ketika menggunakan. Proyek ini tergantung pada SherlockActionBar, jadi itu perlu direferensikan di project.properties, tetapi itu mengacaukan kompilasi, jadi sekarang saya cukup mengetik gitadddan menambahkan semua perubahan ke git tanpa harus menghapus project.properties setiap saat.

Anthony Naddeo
sumber
Saya tidak tahu apa yang --terjadi sampai komentar Anda. Menurut halaman manual, ini opsional dan tidak mengubah hasil dari perintah (setidaknya dalam kasus ini). Pertanyaan ini tampaknya mendukung hal itu, stackoverflow.com/questions/17800994/… . Koreksi saya jika saya salah, tetapi tampaknya itu berarti "memperlakukan apa pun setelah --sebagai argumen, bukan opsi / switch"
Anthony Naddeo
Bagus penggunaan --di git checkoutsaya lihat di pertanyaan itu. Saya tidak tahu apa dasbor ganda sampai pertukaran kita juga. Saya bertanya-tanya apakah git checkoutambiguitas antara cabang dan file dapat mempengaruhi, dalam bentuk ini atau yang berbeda, git resetjuga.
Giulio Piancastelli
10

Untuk menyimpan perubahan dalam file tetapi tidak untuk melakukan saya melakukan ini

git add .

git reset -- main/dontcheckmein.txt

git commit -m "commit message"

untuk memverifikasi file dikecualikan lakukan

git status

Gsumk
sumber
4

Gunakan git add -Auntuk menambahkan semua file yang dimodifikasi dan baru ditambahkan sekaligus.

Contoh

git add -A
git reset -- main/dontcheckmein.txt
Dhanuka Nuwan
sumber
4
git add .
git reset main/dontcheckmein.txt
Daniel Danielecki
sumber
1

Untuk kasus khusus dalam pertanyaan, cara termudah adalah dengan menambahkan semua file dengan ekstensi .c dan tinggalkan yang lainnya:

git add *.c

Dari git-scm (atau / dan man git add):

git tambahkan <pathspec> ...

File untuk menambahkan konten. Fileglobs (mis. * .C) dapat diberikan untuk menambahkan semua file yang cocok. <...>

Perhatikan bahwa ini berarti Anda juga dapat melakukan sesuatu seperti:

git add **/main/*

untuk menambahkan semua file (yang tidak diabaikan) yang ada di mainfolder. Anda bahkan bisa menjadi liar dengan pola yang lebih rumit:

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

Di atas akan menambahkan semua file yang ada di s(any char)cfolder dan memiliki Servicenama file di suatu tempat.

Jelas, Anda tidak terbatas pada satu pola per perintah. Artinya, Anda bisa meminta git untuk menambahkan semua file yang memiliki ekstensi .c dan .h :

git add *.c *.h

Tautan ini mungkin memberi Anda beberapa ide pola glob.

Saya merasa ini sangat berguna ketika saya membuat banyak perubahan, tetapi masih ingin komitmen saya untuk tetap atom dan mencerminkan proses bertahap daripada campur aduk perubahan yang mungkin saya kerjakan saat itu. Tentu saja, pada titik tertentu biaya untuk membuat pola yang rumit melebihi biaya menambahkan file dengan metode yang lebih sederhana, atau bahkan satu file pada satu waktu. Namun, sebagian besar waktu saya dengan mudah dapat menunjukkan dengan tepat file yang saya butuhkan dengan pola sederhana, dan mengecualikan yang lainnya.

Ngomong-ngomong, Anda mungkin perlu mengutip pola glob Anda agar bisa berfungsi, tetapi ini tidak pernah terjadi pada saya.

cegas
sumber
0

Saya menggunakan git add --patchsedikit dan ingin sesuatu seperti ini untuk menghindari keharusan memukul dsepanjang waktu melalui file yang sama. Saya membuat beberapa alias git yang sangat rumit untuk menyelesaikan pekerjaan:

[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' )"

Dalam kasus saya, saya hanya ingin mengabaikan file kecil tertentu sepanjang waktu, tetapi Anda dapat membuatnya menggunakan variabel lingkungan seperti $GIT_EXCLUDE_PATTERNuntuk kasus penggunaan yang lebih umum.

Chris
sumber
0

Perubahan yang harus dilakukan: (gunakan "git reset HEAD ..." untuk unstage)

colin rickels
sumber
0

Anda dapat mencoba ini: git add * && git reset main/dontcheckmein.txt

Rodrigo
sumber