Копить только один файл из нескольких файлов, которые были изменены до git 2.13 - PullRequest
2764 голосов
/ 15 июня 2010

Как я могу сохранить только один из нескольких измененных файлов в моей ветке?

Ответы [ 29 ]

11 голосов
/ 11 июля 2014

Сохраните следующий код в файл, например, с именем stash. Использование stash <filename_regex>. Аргумент - это регулярное выражение для полного пути к файлу. Например, чтобы спрятать a / b / c.txt, stash a/b/c.txt или stash .*/c.txt и т. Д.

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

Код для копирования в файл:

#! /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
    }
  }
}
7 голосов
/ 13 апреля 2017

Я бы использовал git stash save --patch.Я не считаю, что интерактивность раздражает, потому что во время нее есть опции для применения желаемой операции ко всем файлам.

7 голосов
/ 11 января 2016

Это можно легко сделать в 3 шага, используя SourceTree.

  1. Временно зафиксировать все, что вы не хотите спрятать.
  2. Git добавить все остальное, а затем спрятать его.
  3. Выгрузите ваш временный коммит, запустив git reset, нацелив коммит перед вашим временным.

Все это можно сделать в считанные секунды в SourceTree, где вы можете просто нажать нафайлы (или даже отдельные строки), которые вы хотите добавить.После добавления просто передайте их во временную фиксацию.Далее, установите флажок, чтобы добавить все изменения, затем нажмите stash, чтобы спрятать все.С сохраненными изменениями в пути, взгляните на ваш список коммитов и запишите хеш для коммита перед вашим временным коммитом, затем запустите 'git reset hash_b4_temp_commit', который в основном похож на "выталкивание" коммита путем сброса вашей ветви всовершить прямо перед этим.Теперь у вас осталось только то, что вы не хотели спрятать.

7 голосов
/ 27 сентября 2011

Проблема с "промежуточным" решением VonC по копированию файлов за пределы репозитория Git заключается в том, что вы теряете информацию о пути, что делает копирование нескольких файлов позже в некоторой стычке.

Найти егопроще использовать tar (вероятно, схожие инструменты) вместо копии:

  • tar cvf /tmp/stash.tar путь / к / some / путь к файлу / к / some / other / file (... и т. д.)
  • git checkout path / to / some / путь к файлу / to / some / other / file
  • git stash
  • tar xvf / tmp / stash.смола
  • и т. д.(см. «промежуточное» предложение VonC)
7 голосов
/ 13 марта 2014

Иногда я вносил несвязанные изменения в свою ветку, прежде чем зафиксировать ее, и я хочу переместить ее в другую ветку и зафиксировать ее отдельно (например, master). Я делаю это:

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>...

Обратите внимание, что первые stash & stash pop могут быть удалены, вы можете перенести все свои изменения в ветку master при оформлении заказа, но только если нет конфликтов. Также, если вы создаете новую ветку для частичных изменений, вам понадобится тайник.

Вы можете упростить его, если нет конфликтов и нет новой ветки:

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

Тайник даже не нужен ...

6 голосов
/ 14 декабря 2016

Каждый ответ здесь такой сложный ...

А как насчет "заначки":

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

Это чтобы вернуть файл обратно:

git apply /tmp/stash.patch

Точно такое же поведение, как при сохранении одного файла и его повторном подключении.

5 голосов
/ 09 марта 2019

Если вы не хотите указывать сообщение с вашими сохраненными изменениями, передайте имя файла после двойной тире.

$ git stash -- filename.ext

Если это неотслеживаемый / новый файл, вам придется сначала подготовить его.

Этот метод работает в версиях git 2.13 +

3 голосов
/ 29 марта 2017

Решение

Локальные изменения:

  • file_A (модифицированный) не в постановке
  • file_B (модифицированный) не в постановке
  • file_C (модифицированный) не в постановке

Чтобы создать тайник "my_stash" только с изменениями 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}

Готово.


Объяснение

  1. добавить file_C в область подготовки
  2. создать временный тайник с именем "temp_stash" и сохранить изменения в file_C
  3. создать требуемый тайник ("my_stash") только с изменениями в file_C
  4. примените изменения в "temp_stash" (file_A и file_B) к своему локальному коду и удалите тайник

Вы можете использовать git status между шагами, чтобы увидеть, что происходит.

3 голосов
/ 22 марта 2017

Я просмотрел ответы и комментарии для этой и нескольких похожих тем. Имейте в виду, что ни одна из следующих команд не является правильной с целью сохранения любых определенных отслеживаемых / неотслеживаемых файлов :

  • git stash -p (--patch): выбор фрагментов вручную, за исключением неотслеживаемых файлов
  • git stash -k (--keep-index): хранить все отслеживаемые / неотслеживаемые файлы и хранить их в рабочем каталоге
  • git stash -u (--include-untracked): хранить все отслеживаемые / неотслеживаемые файлы
  • git stash -p (--patch) -u (--include-untracked): недопустимая команда

В настоящее время наиболее разумным способом сохранения любых определенных отслеживаемых / неотслеживаемых файлов является:

  • Временно фиксируйте файлы, которые вы не хотите хранить
  • Добавить и прятать
  • Pop временного коммита

Я написал простой скрипт для этой процедуры в ответ на другой вопрос , и здесь есть шагов для выполнения процедуры в SourceTree здесь .

2 голосов
/ 19 апреля 2013

В этой ситуации я git add -p (интерактивно), git commit -m blah и затем прячу то, что осталось, если необходимо.

...