Simpan hanya satu file dari banyak file yang telah berubah dengan Git?

3071

Bagaimana saya bisa menyimpan hanya satu dari banyak file yang diubah di cabang saya?

Rachel
sumber
109
Saya tidak berpikir jawaban diterima bukzor adalah jawaban yang benar untuk pertanyaan seperti yang ditanyakan. git stash --keep-indexmemang menjaga indeks, tetapi menyimpan semua - baik dalam indeks dan keluar.
Raman
@Antonio Menurut saya karunia Anda sebenarnya harus menjadi pertanyaan terpisah, karena pertanyaan awal tidak ada hubungannya dengan TortoiseGit secara khusus.
JesusFreke
1
@ JesusFreke Yep, mengingat hasilnya saya bisa menyelamatkan 50 rep :) Hanya saja ini adalah pertanyaan yang Anda arahkan ke jika Anda mencoba mencari "parash tortoisegit simpanan parsial". Tortoisegit tampaknya tidak menjadi topik populer di sini stackoverflow.com/questions/tagged/tortoisegit
Antonio
7
>>>>>>>>> git diff -- *filename* > ~/patchlalu git checkout -- *filename*dan kemudian Anda dapat menerapkan kembali tambalan dengangit apply ~/patch
neaumusic
36
Sebagian besar jawaban yang ada di bawah sudah usang. Sejak Git 2.13 (Q2 2017) didukung dengan git stash push [--] [<pathspec>...].
Ohad Schneider

Jawaban:

1372

Penafian : jawaban berikut untuk git sebelum git 2.13. Untuk git 2.13 dan lebih, periksa jawaban lain lebih jauh .


Peringatan

Seperti disebutkan dalam komentar, ini menempatkan semuanya ke simpanan, baik dipentaskan dan tidak dipentaskan. --Keep-index hanya meninggalkan indeks setelah simpanan selesai. Ini dapat menyebabkan penggabungan konflik saat nanti Anda menghapus simpanan.


Ini akan menyimpan semua yang belum Anda tambahkan sebelumnya. Hanya git addhal-hal yang ingin Anda simpan, kemudian jalankan.

git stash --keep-index

Misalnya, jika Anda ingin membagi komit lama menjadi lebih dari satu perubahan, Anda dapat menggunakan prosedur ini:

  1. git rebase -i <last good commit>
  2. Tandai beberapa perubahan sebagai edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Perbaiki semua yang diperlukan. Jangan lupa untuk git addperubahan apa pun.
  7. git commit
  8. git stash pop
  9. Ulangi, dari # 5, sesuai kebutuhan.
  10. git rebase --continue
bukzor
sumber
47
Saya menemukan pendekatan ini jauh lebih sederhana: stackoverflow.com/a/5506483/457268
k0pernikus
561
Saya tidak yakin mengapa ini dibalik. Setiap orang pasti memiliki harapan yang berbeda dari saya. Posting asli bertanya "bagaimana cara menyimpan hanya sebagian dari perubahan yang tidak dikomit?" Saat saya gunakan git stash save -k, ya indeks (hijau masuk git stat) dipertahankan, tetapi seluruh perubahan (hijau dan merah) masuk ke simpanan. Ini melanggar permintaan OP, "sembunyikan hanya beberapa perubahan". Saya ingin menyembunyikan hanya beberapa merah (untuk penggunaan di masa depan).
Pistos
70
Jika Anda lebih tertarik pada jawaban atas pertanyaan yang diajukan oleh @Pistos (seperti saya), maka lihat di sini: stackoverflow.com/questions/5506339/…
Raman
27
@Aman: Luar biasa! git stash -ppersis apa yang saya cari. Saya ingin tahu apakah saklar ini baru saja ditambahkan.
Pistos
14
PERINGATAN: git stash --keep-indexrusak. Jika Anda membuat lebih banyak perubahan, maka cobalah git stash popnanti Anda mendapat konflik penggabungan karena simpanan menyertakan file yang Anda ubah, bukan hanya yang tidak Anda pertahankan. Misalnya: Saya mengubah file A dan B, kemudian menyimpan B, karena saya ingin menguji perubahan dalam A; Saya menemukan masalah dengan A yang kemudian saya perbaiki; Saya melakukan A; Sekarang saya tidak dapat melepaskan karena versi lama A ada di simpanan tanpa alasan yang baik yang menyebabkan konflik gabungan. Dalam prakteknya A dan B mungkin banyak file, bahkan mungkin gambar biner atau sesuatu, jadi pada dasarnya saya harus menyerah dan kehilangan B.
rjmunro
3015

Anda juga bisa menggunakan git stash save -p "my commit message" . Dengan cara ini Anda dapat memilih bakhil yang harus ditambahkan ke simpanan, seluruh file juga dapat dipilih.

Anda akan diminta dengan beberapa tindakan untuk setiap potongan:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help
konrad.kruczynski
sumber
5
Bukan itu. Itu dipinjam dari Darcs, sekitar 7 tahun setelah fakta.
Nomen
6
Saya seorang pecandu TortoiseGit. Namun TortoiseGit tidak mendukung stash -p. Saya memberikan jawaban ini karena itu tetap yang paling interaktif / ramah pengguna.
Antonio
27
Anda mungkin ingin menambahkan git stash save -p my stash message:; karena urutan argumenst tidak terlalu intuitif ...
Chris Maes
15
Antara ini dan git log -p, saya pikir -pbendera harus berarti "melakukan hal keren yang saya inginkan tetapi tidak tahu bagaimana mengekspresikannya."
Kyle Strand
2
mengapa jawaban yang bagus ini ada di posisi 12 ?? setelah semua yang 0, +1, +2 jawaban ??????
DenisFLASH
550

Karena git pada dasarnya tentang mengelola semua konten dan indeks penyimpanan (dan bukan satu atau beberapa file), git stashkesepakatan, tidak mengherankan,dengan semua direktori yang berfungsi.

Sebenarnya, sejak Git 2.13 (Q2 2017), Anda dapat menyimpan file individual, dengan git stash push:

git stash push [--] [<pathspec>...]

Ketika pathspecdiberikan ke ' git stash push', simpanan baru merekam status yang dimodifikasi hanya untuk file yang cocok dengan pathspec. Lihat " Menyimpan perubahan ke file tertentu " untuk informasi lebih lanjut.

Contoh sederhana:

 git stash push path/to/file

Kasing uji untuk fitur ini menunjukkan beberapa opsi lagi:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

Jawaban asli (di bawah, Juni 2010) adalah tentang memilih secara manual apa yang ingin Anda sembunyikan.

Komentar Casebash :

Ini ( stash --patchsolusi asli) bagus, tetapi sering saya sudah memodifikasi banyak file sehingga menggunakan tambalan mengganggu

bukzor 's jawaban (upvoted, November 2011) menyarankan solusi yang lebih praktis, berdasarkan
git add+git stash --keep-index .
Pergi dan lihat jawabannya, yang seharusnya jawaban resmi (bukan milik saya).

Tentang opsi itu, chhh menunjukkan alur kerja alternatif di komentar:

Anda harus " git reset --soft" setelah simpanan untuk mendapatkan pementasan yang jelas kembali:
Untuk sampai ke keadaan semula - yang merupakan area pementasan yang jelas dan hanya dengan beberapa modifikasi un-staged, seseorang dapat dengan lembut mengatur ulang indeks untuk mendapatkan (tanpa melakukan hal seperti Anda - bukzor - lakukan).


(Jawaban asli Juni 2010: simpanan manual)

Namun, git stash save --patchdapat memungkinkan Anda untuk mencapai simpanan parsial yang Anda kejar:

Dengan --patch, Anda dapat secara interaktif memilih bakhil dari dalam perbedaan antara KEPALA dan pohon yang akan disimpan.
Entri simpanan dikonstruksi sedemikian sehingga status indeksnya sama dengan status indeks repositori Anda, dan tabel kerjanya hanya berisi perubahan yang Anda pilih secara interaktif. Perubahan yang dipilih kemudian dibatalkan dari meja kerja Anda.

Namun itu akan menyimpan indeks penuh (yang mungkin bukan yang Anda inginkan karena mungkin termasuk file lain yang sudah diindeks), dan sebagian worktree (yang bisa terlihat seperti yang Anda ingin menyimpan).

git stash --patch --no-keep-index

mungkin lebih cocok.


Jika --patchtidak berhasil, proses manual mungkin:

Untuk satu atau beberapa file, solusi perantara adalah dengan:

  • salin di luar repo Git
    (Sebenarnya, eleotlecram mengusulkan alternatif yang menarik )
  • git stash
  • salin kembali
  • git stash # kali ini, hanya file yang Anda inginkan yang disimpan
  • git stash pop stash@{1} # Terapkan ulang semua modifikasi file Anda
  • git checkout -- afile # reset file ke konten KEPALA, sebelum ada modifikasi lokal

Pada akhir proses yang agak rumit itu, Anda hanya akan memiliki satu atau beberapa file yang disimpan.

VONC
sumber
3
Ini bagus, tetapi sering saya memodifikasi banyak file sehingga menggunakan tambalan itu mengganggu
Casebash
6
@VonC: Gaya yang baik untuk memiliki hanya satu jawaban per Jawaban. Juga, menyalin-menempelkan jawaban orang lain ke Anda sendiri adalah perilaku buruk.
bukzor
3
@bukzor: Saya minta maaf jika jawaban yang saya edit sepertinya tidak pantas. Tujuan saya satu-satunya adalah memberi jawaban Anda lebih banyak visibilitas. Saya telah mengedit kembali posting saya, agar maksud itu lebih jelas.
VonC
1
@ Kal: true, stackoverflow.com/a/13941132/6309 menyarankan git reset(campuran)
VonC
3
git is fundamentally about managing a all repository content and index and not one or several files- implementasi itu menaungi masalah yang sedang dipecahkan; itu penjelasan, tapi bukan pembenaran. Setiap sistem kontrol sumber IS tentang "mengelola beberapa file". Lihat saja, komentar apa yang paling banyak dipilih.
Victor Sergienko
90

Ketika git stash -p(atau git add -pdengan stash --keep-index) terlalu rumit, saya merasa lebih mudah digunakan diff, checkoutdan apply:

Untuk "menyimpan" file / dir tertentu saja:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Lalu sesudahnya

git apply stashed.diff
kebiru-biruan
sumber
1
Alternatif yang menarik untuk git add -psaya sebutkan dalam jawaban saya sendiri di atas. +1.
VonC
11
Perhatikan bahwa jika Anda memiliki file biner (seperti PNG), file tersebut tidak akan di-output ke file diff. Jadi ini bukan solusi 100%.
void.pointer
1
@RobertDailey: Itu poin yang menarik bagi saya, karena git diff > file.diffdan git applymerupakan alat simpanan parsial saya yang biasa. Saya mungkin harus mempertimbangkan untuk beralih ke git stash -pperubahan yang lebih besar.
thekingoftruth
1
@thekingoftruth Berikut adalah alias saya gunakan untuk membuat file patch yang, dan itu tidak binari dukungan: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Catatan, bagaimanapun, ini membutuhkan perubahan Anda untuk tambalan untuk dilakukan.
void.pointer
2
Ini tidak berfungsi dengan baik untuk saya jika file yang akan disimpan adalah sesuatu seperti ../../foo/bar.txt. Patch menghasilkan OK, tetapi saya kemudian harus pindah ke root repositori untuk mendapatkan patch untuk diterapkan. Jadi jika Anda mengalami masalah dengan ini - pastikan Anda melakukannya dari direktori root repositori.
Michael Anderson
86

Gunakan git stash push, seperti ini:

git stash push [--] [<pathspec>...]

Sebagai contoh:

git stash push -- my/file.sh

Ini tersedia sejak Git 2.13, dirilis pada musim semi 2017.

sandstrom
sumber
1
Tapi saya git stash pushsudah menyebutkan jawaban saya di atas Maret lalu, 5 bulan lalu. Dan saya merinci perintah Git 2.13 baru di sini: stackoverflow.com/a/42963606/6309 .
VonC
Saya senang bahwa Git maju sangat cepat, untuk waktu yang lama ini tidak mungkin dan kemudian 2.13 dirilis dan tiba-tiba ada solusi sederhana yang tersedia!
sandstrom
1
@VonC Anda benar, Anda juga menyebutkan jawaban yang benar, namun, di antara kedua jawaban itu, yang ini lebih mudah dibaca (tidak ada teks yang membingungkan dan ada juga contoh). Mungkin mereka seharusnya mengedit jawaban Anda
Utopik
@Utopik Anda memiliki saya di "Anda benar" ... tapi ya, saya telah mengedit jawaban saya untuk memasukkan contoh.
VonC
Apakah kemudian digunakan git stash applyuntuk memulihkan perubahan yang disimpan?
Chad
49

Katakanlah Anda memiliki 3 file

a.rb
b.rb
c.rb

dan Anda ingin menyimpan hanya b.rb dan c.rb tetapi tidak a.rb

Anda dapat melakukan sesuatu seperti ini

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

Dan Anda selesai! HTH.

venkatareddy
sumber
29

Cara lain untuk melakukan ini:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

Saya datang dengan ini setelah saya (sekali lagi) datang ke halaman ini dan tidak suka dua jawaban pertama (jawaban pertama tidak menjawab pertanyaan dan saya tidak suka bekerja dengan -pmode interaktif).

Idenya sama dengan apa yang disarankan @VonC menggunakan file di luar repositori, Anda menyimpan perubahan yang Anda inginkan di suatu tempat, menghapus perubahan yang tidak Anda inginkan di simpanan Anda, dan kemudian menerapkan kembali perubahan yang Anda pindah dari jalan. Namun, saya menggunakan simpanan git sebagai "suatu tempat" (dan sebagai hasilnya, ada satu langkah ekstra di akhir: menghapus cahnges yang Anda masukkan ke simpanan, karena Anda juga memindahkannya).

Jasper
sumber
1
Saya lebih suka pendekatan ini. Ini memberikan alur kerja yang mudah di tortoisegit hanya menggunakan simpanan dan kembalikan perintah.
Mark Ch
Mengacu pada jawaban pada SO menggunakan posisi tidak dianjurkan. Posisi berubah seiring perubahan peringkat.
Bryan Ash
2
@BryanAsh Ya, ini tidak penting di sini. Saya memberikan anekdot daripada benar-benar merujuk pada jawaban lain. Pesannya adalah bahwa saya tidak suka jawaban yang disukai masyarakat dan bukan apa yang sebenarnya terkandung dalam jawaban ini. Selain itu, selisih 900 suara antara jawaban kedua dan ketiga membuat ini tidak mungkin berubah dalam waktu dekat, dan jika itu akan pernah berubah saya selalu dapat mengeditnya untuk mengatakan "jawaban atas pada saat itu". Sungguh, saya tidak melihat bagaimana ini merupakan masalah dalam situasi ini.
Jasper
23

Pembaruan (14/02/2015) - Saya telah menulis ulang skrip sedikit, untuk menangani kasus konflik dengan lebih baik, yang sekarang harus disajikan sebagai konflik yang tidak dihapus daripada file .rej.


Saya sering merasa lebih intuitif untuk melakukan kebalikan dari pendekatan @ bukzor. Yaitu, untuk melakukan beberapa perubahan, dan kemudian menyimpan hanya perubahan yang dipentaskan itu.

Sayangnya, git tidak menawarkan simpanan git - hanya indeks atau sejenisnya, jadi saya membuat skrip untuk melakukan ini.

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

Anda dapat menyimpan skrip di atas sebagai git-stash-indexsuatu tempat di jalur Anda, dan kemudian dapat memanggilnya sebagai git stash-index

# <hack hack hack>
git add <files that you want to stash>
git stash-index

Sekarang simpanan berisi entri baru yang hanya berisi perubahan yang telah Anda lakukan, dan pohon kerja Anda masih mengandung perubahan yang tidak bertahap.

Dalam beberapa kasus, perubahan pohon kerja mungkin tergantung pada perubahan indeks, jadi ketika Anda menyimpan indeks perubahan, perubahan pohon kerja memiliki konflik. Dalam hal ini, Anda akan mendapatkan konflik tidak terputus yang biasa Anda dapat atasi dengan git merge / git mergetool / etc.

JesusFreke
sumber
Rekomendasikan pushdalih-alih cddan popddi akhir skrip jadi jika skrip berhasil, pengguna berakhir di direktori yang sama seperti sebelum menjalankannya.
Nate
1
@Nate: sejauh yang saya tahu, seharusnya hanya mengubah direktori untuk pengguna jika mereka menggunakan skrip. Jika Anda menjalankan skrip secara normal (~ / bin / git-stash-index), atau melalui git (git stash-index), skrip dijalankan di sesi terminal terpisah, dan setiap perubahan direktori kerja pada sesi itu tidak memengaruhi direktori kerja di sesi terminal pengguna. Apakah Anda mengetahui kasus penggunaan umum saat ini tidak benar? (Selain dari sumber naskah, yang saya tidak akan menganggap "umum")
JesusFreke
20

Jika Anda tidak ingin menentukan pesan dengan perubahan simpanan Anda, berikan nama file setelah tanda hubung ganda.

$ git stash -- filename.ext

Jika ini file yang tidak dilacak / baru, Anda harus mengaturnya terlebih dahulu.

Metode ini bekerja di git versi 2.13+

sealocal
sumber
Jawaban itu verbose, ini singkat. Jika itu membantu seseorang, saya akan meninggalkannya. Tidak ada seorang pun di halaman ini yang menyebutkan sintaks dan hasil ini - mereka malah menyebutkan `git stash push`.
sealocal
Ini jawaban yang saya cari. Terima kasih! +1
nicodp
19

Karena membuat cabang di Git sepele, Anda bisa membuat cabang sementara dan memeriksa masing-masing file di dalamnya.

shangxiao
sumber
2
Anda tidak dapat membuat cabang dengan pengeditan yang tidak bertahap. Anda dapat dengan mudah memindahkan semua suntingan ke cabang baru (simpanan / simpanan pop) tetapi kemudian Anda kembali ke awal: bagaimana Anda menguji cabang Anda hanya dengan beberapa suntingan itu, tanpa kehilangan yang lainnya?
bukzor
7
Anda tidak dapat berganti cabang jika Anda memiliki perubahan lokal. Namun, Anda dapat membuat cabang baru dan secara selektif menambahkan / mengkomit file, dan kemudian membuat cabang lain dan melakukan hal yang sama secara rekursif ... kemudian checkout cabang asli dan secara selektif bergabung kembali. Saya baru saja melakukannya. Ini sebenarnya tampak cara alami untuk melakukan sesuatu, karena Anda pada dasarnya membuat cabang fitur.
iain
3
@ iain Anda bisa berganti cabang jika Anda memiliki perubahan lokal, asalkan mereka tidak membutuhkan penggabungan. Lihat Contoh Intis . Ini berlaku setidaknya untuk Git v2.7.0.
Colin D Bennett
18

Anda cukup melakukan ini:

git stash push "filename"

atau dengan pesan opsional

git stash push -m "Some message" "filename"
vinodsaluja
sumber
1
Ini menambahkan tidak ada yang baru. Dorongan simpanan Git telah disebutkan dalam beberapa jawaban
JesusFreke
12

Simpan kode berikut ke file, misalnya, dinamai stash. Penggunaan adalah stash <filename_regex>. Argumennya adalah ekspresi reguler untuk path lengkap file. Misalnya, untuk menyembunyikan a / b / c.txt, stash a/b/c.txtatau stash .*/c.txt, dll.

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Kode untuk disalin ke file:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}
aprikot
sumber
2
Metode yang bagus. Saya akan memilih ini sebagai jawabannya. Kiat untuk pembaca masa depan: Anda harus mencocokkan pada jalur penuh. misalnya stash subdir / foo.c
er0
12

Kalau-kalau Anda benar-benar bermaksud membuang perubahan setiap kali Anda menggunakan git stash(dan tidak benar-benar menggunakan simpanan git untuk menyembunyikannya sementara), dalam hal ini Anda dapat menggunakan

git checkout -- <file>

[ CATATAN ]

Itu git stashhanya alternatif yang lebih cepat dan sederhana untuk bercabang dan melakukan hal-hal.

Devesh
sumber
8

Masalah dengan solusi `perantara 'VonC untuk menyalin file ke luar repo Git adalah bahwa Anda kehilangan informasi path, yang membuat menyalin banyak file di kemudian hari dengan sedikit kerumitan.

A merasa lebih mudah menggunakan tar (alat serupa mungkin akan melakukannya) daripada menyalin:

  • tar cvf /tmp/stash.tar path / ke / some / path file / ke / some / other / file (... etc.)
  • git checkout path / ke / some / path file / ke / some / other / file
  • simpanan git
  • tar xvf /tmp/stash.tar
  • dll. (lihat saran `perantara 'VonC)
eleotlecram
sumber
checkout -ftidak diperlukan, checkout(tanpa -f) sudah cukup, saya sudah memperbarui jawabannya.
eleotlecram
8

Kadang-kadang saya membuat perubahan yang tidak terkait pada cabang saya sebelum saya melakukan itu, dan saya ingin memindahkannya ke cabang lain dan melakukan itu secara terpisah (seperti master). Saya melakukan ini:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

Catatan yang pertama stash& stash popdapat dihilangkan, Anda dapat membawa semua perubahan Anda kemaster cabang saat Anda checkout, tetapi hanya jika tidak ada konflik. Juga jika Anda membuat cabang baru untuk perubahan parsial Anda akan membutuhkan simpanan.

Anda dapat menyederhanakannya dengan asumsi tidak ada konflik dan tidak ada cabang baru:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

Stash bahkan tidak diperlukan ...

void.pointer
sumber
8

Ini dapat dilakukan dengan mudah dalam 3 langkah menggunakan SourceTree.

  1. Lakukan sementara semua yang tidak Anda inginkan disimpan.
  2. Git menambahkan yang lainnya, lalu menyimpannya.
  3. Pop komit sementara Anda dengan menjalankan git reset, menargetkan komit sebelum Anda sementara.

Ini semua bisa dilakukan dalam hitungan detik di SourceTree, di mana Anda bisa mengklik file (atau bahkan setiap baris) yang ingin Anda tambahkan. Setelah ditambahkan, cukup komit ke komit sementara. Selanjutnya, klik kotak centang untuk menambahkan semua perubahan, lalu klik simpanan untuk menyembunyikan semuanya. Dengan perubahan yang disembunyikan, lihat daftar komit Anda dan catat hash untuk komit sebelum komit sementara Anda, kemudian jalankan 'git reset hash_b4_temp_commit', yang pada dasarnya seperti "membuka" komit dengan menyetel ulang cabang Anda ke ulang komit lakukan tepat sebelum itu. Sekarang, Anda hanya memiliki barang-barang yang tidak ingin disimpan.

Triynko
sumber
8

Saya akan menggunakan git stash save --patch. Saya tidak menemukan interaktivitas yang mengganggu karena ada opsi selama itu untuk menerapkan operasi yang diinginkan ke seluruh file.

Raffi Khatchadourian
sumber
3
Kagum ada sedikit dukungan untuk jawaban ini, itu solusi terbaik tanpa perlu esai.
robstarbuck
Jelas jawaban yang bagus, git stash -pmemungkinkan Anda untuk menyimpan seluruh file dengan cepat dan berhenti sesudahnya.
Richard Dally
7

Setiap jawaban di sini sangat rumit ...

Bagaimana dengan ini untuk "menyembunyikan":

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Ini untuk memunculkan perubahan file kembali:

git apply /tmp/stash.patch

Perilaku yang sama persis seperti menyimpan satu file dan memasukkannya kembali.

Christophe Fondacci
sumber
Saya mencobanya tetapi tidak ada yang terjadi. Ketika saya git applytidak memiliki kesalahan tetapi perubahan tidak dikembalikan juga
ClementWalter
File patch yang Anda buat di / tmp mungkin dihapus. Anda mungkin telah reboot antara diff dan yang berlaku. Coba lokasi lain yang lebih permanen. Itu berhasil. Periksa juga isi file tambalan.
Christophe Fondacci
4

Saya telah meninjau jawaban dan komentar untuk ini dan sejumlah utas serupa. Perlu diketahui bahwa tidak ada dari perintah berikut ini yang benar untuk tujuan dapat menyimpan file terlacak / tidak terlacak tertentu :

  • git stash -p (--patch): pilih bakhil secara manual, tidak termasuk file yang tidak dilacak
  • git stash -k (--keep-index): sembunyikan semua file yang dilacak / tidak dilacak dan simpan di direktori kerja
  • git stash -u (--include-untracked): simpanan semua file yang dilacak / tidak terlacak
  • git stash -p (--patch) -u (--include-untracked): perintah tidak valid

Saat ini, metode paling masuk akal untuk dapat menyimpan file terlacak / tidak terlacak spesifik adalah dengan:

  • Komit sementara file yang Anda tidak ingin simpanan
  • Tambahkan dan simpan
  • Pop komit sementara

Saya menulis skrip sederhana untuk prosedur ini sebagai jawaban atas pertanyaan lain , dan ada langkah - langkah untuk melakukan prosedur di SourceTree di sini .

ZimbiX
sumber
4

Larutan

Perubahan lokal:

  • file_A (dimodifikasi) tidak dipentaskan
  • file_B (dimodifikasi) tidak dipentaskan
  • file_C (dimodifikasi) tidak dipentaskan

Untuk membuat simpanan "my_stash" hanya dengan perubahan pada file_C :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Selesai


Penjelasan

  1. tambahkan file_C ke area pementasan
  2. buat simpanan sementara bernama "temp_stash" dan pertahankan perubahan pada file_C
  3. buat simpanan yang diinginkan ("my_stash") hanya dengan perubahan pada file_C
  4. terapkan perubahan pada "temp_stash" (file_A dan file_B) pada kode lokal Anda dan hapus simpanan

Anda dapat menggunakan status git di antara langkah-langkah untuk melihat apa yang sedang terjadi.

Alex 75
sumber
3

Ketika Anda mencoba untuk beralih di antara dua cabang, situasi ini terjadi.

Coba tambahkan file menggunakan " git add filepath".

Kemudian jalankan baris ini

git stash --keep-index

Sireesh Yarlagadda
sumber
3

Untuk menyimpan satu file digunakan git stash --patch [file].

Ini akan cepat: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Cukup ketik a(simpel bingkah ini dan semua bakhil nanti dalam file) dan Anda baik-baik saja.

Vinicius Brasil
sumber
Hilang pushseperti dalamgit stash push --patch [file]
Filipe Esperandio
@FilipeEsperandio pushhanya berfungsi di versi Git yang lebih baru , dulu save. Dalam kedua kasus pushatau savetersirat dengan memanggil stash: "Memanggil git simpanan tanpa argumen sama dengan git simpanan push", docs
patrick
2

Situasi serupa. Melakukan dan menyadari itu tidak baik.

git commit -a -m "message"
git log -p

Berdasarkan jawaban ini membantu saya.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
David Hrbáč
sumber
2

Dalam situasi ini saya git add -p(interaktif), git commit -m blahdan kemudian menyembunyikan apa yang tersisa jika perlu.

J0hnG4lt
sumber
2

Saya tidak tahu bagaimana melakukannya di command line, hanya menggunakan SourceTree. Katakanlah Anda telah mengubah file A, dan memiliki dua perubahan bakhil di file B. Jika Anda ingin menyembunyikan hanya bingkah kedua di file B dan membiarkan yang lainnya tidak tersentuh, lakukan ini:

  1. Panggung segalanya
  2. Lakukan perubahan pada copy pekerjaan Anda yang membatalkan semua perubahan dalam file A. (mis. Meluncurkan alat diff eksternal dan membuat file cocok.)
  3. Jadikan file B terlihat seolah hanya perubahan kedua yang diterapkan. (mis. luncurkan alat diff eksternal dan batalkan perubahan pertama.)
  4. Buat simpanan menggunakan "Simpan perubahan bertahap".
  5. Unstage segalanya
  6. Selesai!
Juozas Kontvainis
sumber
2
git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)
celikz
sumber
1
Nah, Anda seharusnya tidak melakukan itu. The Answer harus memberikan solusi untuk pertanyaan itu. Anda bisa menanyakan pertanyaan Anda sendiri.
L_J
solusi ini adalah salah satu jawaban termudah untuk pertanyaan INI. baca pertanyaan, bandingkan semua jawaban dan jawab saya maka jika Anda memiliki keraguan bahwa jawaban ini bukan solusi yang berlaku atau tidak cukup informasi tentang pertanyaan, maka kita dapat berbicara lagi.
celikz
Ini tidak akan berhasil, karena perintah ketiga, "git stash" tidak akan menghormati file yang dipentaskan. Kedua, file yang dipentaskan dan yang tidak dipentaskan akan menuju simpanan. Pertanyaan-pertanyaan secara khusus menanyakan bagaimana menyimpan hanya satu file
CyberProdigy
0

Satu cara rumit adalah dengan pertama-tama melakukan segalanya:

git add -u
git commit // creates commit with sha-1 A

Setel ulang kembali ke komit asli tetapi checkout the_one_file dari komit baru:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Sekarang Anda dapat menyimpan the_one_file:

git stash

Bersihkan dengan menyimpan konten yang dikomit dalam sistem file Anda sambil mengatur ulang ke komit asli:

git reset --hard A
git reset --soft HEAD^

Ya, agak canggung ...

Martin G
sumber
0

Saya tidak menemukan jawaban untuk apa yang saya butuhkan dan itu semudah:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Menyimpan tepat satu file.

SCBuergel.eth
sumber
0

Jawaban cepat


Untuk mengembalikan file yang diubah spesifik di git, Anda dapat melakukan baris berikut:

git checkout <branch-name> -- <file-path>

Ini adalah contoh aktual:

git checkout master -- battery_monitoring/msg_passing.py

Benyamin Jafari
sumber
0

Jika Anda ingin menyimpan beberapa file yang diubah, cukup hanya

Tambahkan file yang tidak ingin Anda sembunyikan, di Panggung , Kemudian jalankangit stash save --keep-index

Ini akan menyimpan semua file yang diubah tidak bertahap

Amin Shojaei
sumber