2014-12-30 4 views
2

Недавно я начал использовать SourceTree и Git, но я все еще запутался в отношении штампов/ветвлений и моих рабочих файлов. У меня возникли проблемы с поиском чего-либо, что разъясняет мне все.Смятение/ветвь/рабочая ошибка путаницы

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

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

Итак, что мне интересно, каков идеальный рабочий процесс для этого? Скажем, я разрабатываю две функции одновременно в двух разных ветвях и хочу постоянно прыгать туда-сюда. Должен ли я помнить о том, чтобы хранить мои файлы рабочей копии перед каждым переключением или есть лучший подход к этому?

+0

* Если я хочу переключить ветви, он автоматически запустит мою рабочую копию, прежде чем переключиться на новую ветку. * Нет! Если у вас есть незафиксированные изменения, конфликтующие с веткой, которую вы проверяете, Git не позволит вам это сделать. Вам нужно будет их вручную «вручную»; Git не делает это автоматически для вас. – Jubobs

+0

Хорошо бы знать, что я не просто что-то пропустил. Я предполагаю, что всплывающее окно из SourceTree, спрашивающее, хотите ли вы отменить локальные изменения, также должно выступать в качестве напоминания о блокировке их перед переключением. – Mathieson

+0

Я считаю, что у вас будет гораздо лучший опыт, если вы используете Git из командной строки, но это только мое мнение. В частности, я не уверен, позволяет ли SourceTree определять псевдонимы/макросы. – Jubobs

ответ

1

Если я должен переключить ветви, он автоматически спрячет мою рабочую копию, прежде чем переключиться на новую ветку.

Nope! Git автоматически не устанавливает для вас местные изменения. Кроме того, если у вас есть незафиксированные изменения, конфликтующие с веткой, которую вы проверяете, Git не позволит вам проверить интересующую ветку. Вам необходимо либо отбросить, либо спрятать их «вручную», прежде чем проверять эту другую ветку.

Мне кажется довольно понятным, что [...] ваши рабочие файлы копирования полностью независимы от ваших ветвей, как и пристыковки.

Да, и для этого есть веские причины. В частности, один прецедент для блокировки - это когда вы начинаете делать изменения, пока выдается «неправильная» ветка. Вы можете выйти из неприятностей,

  • припрятать локальные изменения (что посадка в чистом рабочем состоянии),
  • проверить «правильную» ветвь,
  • сования, что копить, чтобы восстановить ваши локальные изменения ,

Say Я разрабатываю две функции одновременно в двух различных отраслях и хотят постоянно прыгать туда и обратно. Должен ли я помнить о том, чтобы хранить мои файлы рабочей копии перед каждым переключением или есть лучший подход к этому?

Да, сменяя ваши изменения перед тем, как переключиться на другую ветвь, а затем вытащить предыдущий тайник, это будет обычный рабочий процесс. Если вы часто переключаете ветви, это действительно утомительно, но если вы используете Git из командной строки, вы можете определить aliases, чтобы отвлечь часть этой сложности.

Я никогда не использовал SourceTree самостоятельно, но я могу себе представить, как это забивание/проверка/всплытие может включать в себя довольно много утомительных щелчков мыши. По-видимому, хотя SourceTree представил механизм под названием «Custom Actions», который позволяет вам определять свои собственные команды, including Git commands. Возможно, вы захотите изучить его ...

2

Раздел «TL; DR»: остерегайтесь просто слепо делать git stash save && git checkout ... && git stash pop.


На самом деле есть несколько частей, которые вы можете разделить, особенно при использовании интерфейса командной строки git.

В частности, «текущая ветка», если таковая имеется, представляет собой просто элемент, записанный в файле (файл, содержащий ссылку HEAD, .git/HEAD). Рассматривая исходное содержимое этого файла, вы обычно увидите ref: refs/heads/master и тому подобное. (В режиме «отсоединенный HEAD» вместо этого вы увидите необработанный SHA-1.) Есть команды низкого уровня git, которые будут обновлять HEAD, не делая ничего другого.

Однако большинство людей в основном переключают ветви с помощью git checkout, что, помимо правильного пути :-), чтобы сделать это, имеет встроенный ряд защит. В основном, он откажется переключать ветви, если у вас есть дерево или «индекс» (AKA-кеш), которые будут потеряны таким коммутатором. Допустим, вы находитесь на ветке A, и вы просите переключиться на ветвь B. Процесс проверки должен:

  • получить список всех файлов, которые существуют в наконечнике фиксации филиала A
  • получить список всех файлов, которые существуют в наконечнике фиксации филиала B
  • для файлов первый список, который не находится во втором, удалите эти файлы из файла work-dir
  • для файлов во втором списке, которые не находятся в первом, добавьте эти файлы в рабочий каталог
  • для файлов, находящихся в оба, замените содержимое рабочего каталога, если (и только если) файлы различаются г

Кроме того, выезд осуществляется «писать через» кэш: если файл F отличается A и B содержимое версии B сначала должны быть скопированы в индексную/кэш, а затем записывается в рабочий каталог.

Если вы устроили (с git add) некоторой модификацией в файл F, или у Вас есть ип-ступенчатая модификация F в вашем рабочем каталоге, этот процесс проверки будет перезаписывать те поставил или отменить изменения в постановке, так git checkout остановок с сообщением об ошибке. Если файл F должен быть удален, это также приведет к перезаписи (или, точнее, удалению) ваших изменений, поэтому снова остановится checkout.

С другой стороны, если файл Fэто то же самое в обоих фиксаций, то checkout может продолжаться: он просто оставляет непредоставленные совершенные изменения в постановке или unstaged. Вот почему вы можете иногда, но не всегда, просто git checkout филиал, над которым вы хотели работать.


"заначка" Git (как в git stash), как вы видели, независимо от ветвей. Ключевая концепция здесь заключается в том, что каждый тайник - вы можете иметь более одного активного за раз - на самом деле совершить (или, точнее, набор коммитов: два или три, в зависимости от того, что вы застреваете). Прежде чем вы возражаете, что фиксации сделаны на ветках, мы должны сделать еще пару различий. В частности, слово «ветвь» означает две или три разные вещи, в git.

Обязательно всегда (обязательно) переходить в «фиксацию графа», так как график - это просто вещь, образованная всеми коммитами и их ребрами. В той степени, в которой слово «ветвь» означает «часть графа фиксации», эти фиксации запятой находятся на ветвях. Но слово «ветвь» также относится к именам, которые идентифицируют ветвь tip commit, и здесь эти фиксации кошелька не продвигают ответвление. (См this post, также Jubobs, для получения более подробной информации о нескольких значениях «ветви».)

Команда git stash смотрит на текущий индекс/кэш и работа дерева состояние, и делает новые коммиты из них если - это «если» оказывается весьма важным - , если у них есть сохраненные поэтапные или неустановленные изменения. Один из этих новых коммитов (из которых можно найти другие) сохраняется под специальным ссылочным именем stash. Однако ни одна из новых коммитов не добавляется в текущую ветку, поэтому они не находятся в какой-либо именованной ветке. В этом смысле они независимы от текущей ветви, но поскольку они совершают транзакции, у них есть идентификаторы фиксации родителя, и в этом конкретном смысле они привязаны непосредственно к фиксации, которая действовала, когда был выполнен save.

Что это означает для вас, конечный пользователь, часто «ничего»: вам, вероятно, все равно, и вам не все равно. Тем не менее, если вы когда-либо использовали git stash branch, чтобы превратить тайник в ветвь, это означает, что новая ветка будет откидываться от фиксации, прикрепленной к ней. (Это, как выясняется, как правило, именно то, что вы хотите.)


Один из рисков с определением псевдонима или макрос, который делает git stash save && git checkout ... && git stash pop является то, что первый шаг, git stash save, ничего не может сделать.

Если он ничего не делает, если он не нажимает новый штамп на «стежок стека», то он все равно преуспеет, и ваш псевдоним-макрос продолжит проверку другой ветви, а затем (попробуйте) вытащите стопку из стека.

Если в этом стеке есть другой (другой) штамп, который вы хотели использовать где-то в другом месте, ну, вы просто попытались вставить его в ветку, на которую вы только что переключились.

Обратите внимание, что есть два сложены «если» S здесь, два условия, которые должны соблюдаться для этой конкретной ошибки укусить:

  • вам нужно не иметь ничего копить и
  • вам нужно есть некоторые существующие кошельки вы не хотите выскочил.

Один из способов решения этой проблемы - использовать скрипт, а не просто простой псевдоним git, для выполнения последовательности ветвления-переключателя-с-stash.В сценарии вы запускаете git stash, как обычно, но до и после тайника вы проверяете SHA-1, что ссылка stash разрешает, если таковая имеется. Если это изменится, то git stash save сохранил что-то, поэтому есть что поп, и вы можете продолжить последовательность выписки и поп-музыки. Если это не изменится - если не было закладок до и после, или если прикрытие вверху стека все еще находится в верхней части стека, тогда нечего делать, и вы должны просто сделать чек.

Есть еще одна ошибка, которая может вас укусить; см. this answer на несколько иной вопрос, который включает в себя немного кода оболочки, выражающего вышеуказанный «pop», только если save фактически нажал что-то «правило».

+0

Приятно читать, как всегда, но вы бросаете бедного OP (который знает только Git через GUI) в глубоком конце! Хороший бит о том, как «git stash save» может вас укусить. Я этого не осознавал. – Jubobs

+1

Вот почему я добавил бит «TL; DR» вверху :-) – torek

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