2016-04-13 2 views
1

Как я понимаю, Git Stash - это коллекция различий.Если Git Stash сохраняет Diffs, то почему он не может быть применен к другой ветке?

Так, например, если у меня есть целый репозиторий с одним файлом foo.txt

В 32 строк файла просто

Lorem Ipsum 01 
Lorem Ipsum 02 
Lorem Ipsum 03 
... 
Lorem Ipsum 30 
a first line: good 
a second line: bad 

И я совершил все.

Теперь я создаю новую ветвь:

git checkout -b feature123 

И теперь, когда я нахожусь на этой ветке, я меняю слово good к better и bad к worse.

Теперь, только предположим, что мой менеджер программ приходит и говорит: «Срочно! Мы должны изменить 01 на 011 и 02 на 022».

Так что копить изменения, а затем изменить в master отрасли:

git stash 
git checkout master 

и я изменил 01 к 011 и 02 к 022, как он просил.

И сказать, я хочу, чтобы включить изменения, которые я «спрятано» ранее в master отрасли:

git stash apply 

но выдаст ошибку:

error: Your local changes to the following files would be overwritten by merge: 
    foo.txt 
Please, commit your changes or stash them before you can merge. 
Aborting 

Почему? Не может ли он применить набор различий к foo.txt?

(PS Я могу совершить первую, а затем использовать git stash apply, и быть в состоянии применить эти к foo.txt посмотреть различие Но почему не раньше, чем совершить Так git stash на самом деле просто экономит коллекцию файлов изменений - повторить именно:.? Коллекцию из файлов изменений, а затем сделать git checkout . (отказаться от всех изменений) Это правда)

+0

Вы совершили изменения, которые вы сделали, прежде чем пытаться применить изменения stash'd? – sisyphus

+0

@sisyphus Вопрос в том, почему изменения должны быть совершены (или спрятаны), и почему 'git stash' не может« применять »исправления к измененным файлам. – tobiasvl

+1

Это механизм безопасности, я очень рад, что он не будет просто перезаписывать мои изменения, даже если у меня будет возможность их сценировать. – Creynders

ответ

1

man git stash говорит следующее, под pop (который также относится к apply):.?

Рабочий каталог должен соответствовать индекс.

Так вы правильно, он может применить коллекцию в foo.txt файлов изменений, но если у вас есть unstaged локальные изменения. Если вас смущает разница между рабочим каталогом и индексом, может помочь this answer.

Запустите git add hei.txt, и вы сможете применить кейс.

+0

, поэтому я думаю, что фраза «Рабочий каталог должна соответствовать индексу» означает, что все должно быть организовано? (или каждый отслеживаемый файл должен быть поставлен?) Есть ли причина, по которой они должны быть поставлены ... кроме того факта, что эта страница говорит так? (то есть ... в стороне от того, что говорит страница man, действительно ли есть веская причина для этого?) –

+0

@ 太極 者 無極 而 生 git должен знать о ваших локальных изменениях (то есть они должны быть поставлены в индекс) чтобы он мог разрешать конфликты. Когда вы ставите, git создает ref (который вы можете увидеть в 'git reflog'). Когда вы применяете stash, git объединяет stash ref с индексом ref. Это также работает как защитная сетка, в которой вы не можете потерять локальные изменения, если кошелек делает то, что вы не намеревались, потому что git знает о ваших изменениях. – tobiasvl

3

Git Stash - это набор отличий.

Не совсем. stash - это совокупность объектов фиксации, каждый из которых записывает полный моментальный снимок проекта. git stash pop выполняет слияние между текущей головой, ставкой и фиксацией на основе кошелька.

Можно было бы теоретически выполнить слияние на локально-модифицированных файлов, но на практике:

  • Это было бы очень плохая идея для merge, потому что это будет поощрять пользователей делать «зло слияния ", т.е. имеют как связанные с слиянием ручные изменения в одной и той же фиксации. Как следствие, для слияния запрещается касаться локально модифицированных файлов, а stash использует тот же механизм, что и merge, поэтому запрещает его таким же образом.

  • Индекс делает вещи более сложными, чем кажется. Если файл имел неустановленный контент, и вы хотели применить к нему кошелек, тогда не было бы надлежащего способа определить, что должно быть содержимым индекса в конце приложения stash. Фактически, stash pop разрешено касаться файлов, для которых индекс соответствует рабочему дереву.

Примечание: ваша проблема заключается не в том, что вы находитесь на разных ветках, а в том, что у вас есть неуправляемые/неустановленные изменения. Вы делали эти изменения в то время как на ветке feature123, но они сохраняются при переключении ветвей с git checkout master.

+0

скажите, если мое изменение равно 1 символу только в 1 файле, то будет ли stash быть коллекцией объектов commit, но в этом случае всего 1 объект commit? Итак, если я изменил 2 файла, то 2 объекта commit? Как насчет 1 файла, но 1 изменение в строке 1 и 1 изменится на строку 30, затем ... 1 объект фиксации? Или я думаю, что я пытаюсь понять, может ли мы рассматривать его как ... просто неназванный филиал, со всеми файлами, совершенными ... поэтому мы можем «вишнево выбрать» эту фиксацию, чтобы применить изменения к любой другой ситуации ? –

+0

, совершая объекты, вы не имеете в виду полную фиксацию? потому что я знаю, что git сохранит целый новый файл при фиксации, поэтому, если я создам текстовый файл размером 15 МБ, каждая строка в нем будет содержать только 80 символов с номером строки, тогда, если я отредактирую файл только на одну строку и commit, весь каталог теперь составляет 15 МБ. Снова измените 1 строку и зафиксируйте, и теперь весь каталог равен 30 МБ. Теперь, если я создаю новую ветвь функции и переключаюсь туда, отредактируйте 1 строку и сделайте «git stash», весь каталог немного увеличился в размере (1 МБ или меньше). –

+0

(сказал, что ... если я вернусь к основной ветке, измените другую строку и зафиксирую, весь каталог увеличится лишь немного по размеру. Возможно, это связано с сжатием.) –

Смежные вопросы