2015-12-29 5 views
0

Шаг слияния/переадресации git pull слияния/ребас ק удаленная ветка отслеживания в/в текущую ветку.Выполняет ли git pull текущую ветку после шага слияния/переадресации?

Интересно, если git pull, то проверьте текущую ветку в рабочий каталог? Или мне нужно проверить себя?

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

Но я не уверен, что эта операция слияния git pull делает это уже, или я должен сделать это сам после git pull.

ответ

2

Текущая ветка is проверено в рабочем каталоге.

После слияния/переустановки ветвь переместилась вперед к другому фиксации.

Так что да, git проверит, что совершить, чтобы вы оставались в текущей ветке.

+0

(1) ветви (включая текущую ветку) всегда хранятся в репозитории git, а рабочий каталог не находится в репозитории git. Поэтому я не уверен, понимаю ли я, что «Текущая ветка находится в рабочем каталоге». (2) Мой вопрос заключается в моей мысли о том, что шаг слияния изменяет текущую ветвь в репозитории git, в то время как рабочий каталог не обновляется с текущей ветвью, поэтому необходимо проверить измененную текущую ветку на рабочий каталог. Но я не уверен, что этот шаг слияния «git pull» делает это уже, или я должен делать это сам после «git pull». – Tim

+0

Я отредактировал язык в своем ответе. Я говорю, что содержимое в рабочем каталоге * всегда * отражает состояние текущей ветви (если, очевидно, если нет текущей ветви). –

+0

«git будет проверять, что совершить», вы имеете в виду шаг слияния git pull делает это уже, или я должен делать это сам после git pull? – Tim

2

Короткий ответ «нет», и это на самом деле полный и технически правильный ответ, но немного неудовлетворителен и вполне вероятно, вводит в заблуждение: во всех хороших случаях конечное состояние , как будто мерзавец сделал выписка. Тем не менее, вы можете остановиться здесь, если хотите. :-)

Длительный ответ немного длинный и усложняется в современных версиях git, потому что вы можете настроить git rebase на «autostash». Но еще раз мы вернемся к тому, что git pull работает git fetch, за которым следует либо git merge, либо git rebase.

  • fetch шаг проще, потому что не нужно знать или заботиться о работе-каталоге. Он связывается с именем remote (взято из branch.$branch.remote текущей ветки, если вы не указали его), дает удаленные некоторые refspec (ы) (из дополнительных аргументов, которые вы передали, или ваша конфигурация, если вы не прошли какой-либо) и при необходимости переносит коммиты и другие объекты с пульта. Эти коммиты и другие объекты перемещаются в хранилище в вашем репозитории, где они безопасно уходят с пути, но доступны в любое время. Некоторые имена (ветви) удаленной отслеживания могут быть обновлены, и в любом случае ветвь (ы) ветви помещается в специальный файл FETCH_HEAD (в частности, FETCH_HEAD приобретает идентификаторы SHA-1, которые идут с каждой ветвью название главы).

    Чтобы увидеть полное имя/SHA-1 ID, в поле зрения объекта, запустите git ls-remote remote (например, git ls-remote origin). Это связывается с пультом дистанционного управления и получает от него ту же информацию, что и git fetch, а затем распечатывает ее в окне команд. Он ничего не меняет, так что он просто использует небольшую пропускную способность сети, и, на мой взгляд, он довольно образован. (Если есть много веток и меток на пульте дистанционного управления может понадобиться для прокрутки вперед и назад, чтобы увидеть все выходные данные, или сохранить вывод в файл или любой другой.)

  • merge или rebase шаг, где сложными битами. Выйдем из гнездования и рассмотрим два. Давайте также рассмотрим только случай слияния с одной мишенью (т. Е. Обычное каждодневное слияние, а не одно из слияний гибридных git).

Если начать с чистым рабочим деревом (и индекс), это намного проще, чтобы описать то, что происходит сейчас. Давайте начнем с чистого дерева.

fetch шаг, наложенный на некоторые фиксации. merge или rebase находит соответствующую базу слияния или перебазирования назначения, а затем выполняет либо слияние, либо Rebase, как указано:

  • Для слияния, мерзавец находит слияния базу. Обычно это единичная конкретная фиксация. (В некоторых случаях существует несколько кандидатов слияния-база, и мерзавец обрабатывает их тоже, но давайте не будем беспокоиться о них.) Вы можете думать об этом как точка, в которой ваша ветвь и другая ветвь расходились:

    На этой диаграмме каждый маленький узел o обозначает фиксацию. Слияние - это фиксация, отмеченная *, а не o. Самая частая фиксация вашей ветки master является самой правой o в верхней строке, а наибольшая фиксация их ветви origin/master является самой правой o в нижней строке.

    Давайте назовем самую частую фиксацию вашей ветки A, только для конкретности. (Он имеет свой собственный уникальный SHA-1 ID и это его «настоящее имя», но давайте просто называть его A.) Давайте назовем слияние базы B и кончик их ветвей C и перерисовать эту схему:

       o - A  <-- your branch (master) 
          /
    ... - o - B 
          \ 
           o - o - C <-- their branch (origin/master) 
    

    Чтобы выполнить слияние (если требуется слияние), мерзавец начинается с запуска диф между совершить B и совершить A, как если бы вы делали git diff B A (заполнение фактической SHA-1 для B и A конечно, и он использует внутренняя версия его кода diff, а не просто чтение через буквальный текст git diff). Этот diff сообщает git «что вы изменили» с общей базой B.

    Далее git запускает git diff B C (внутренний формат, конечно же, конечно). Этот diff сообщает git «что они изменили» с той же общей базы.

    И, наконец, git пытается объединить два различия. Если вы добавили файл, и они этого не сделали, git сохранит ваш добавленный файл. Если вы изменили правописание neighbor на neighbour в файле README, и они этого не сделали, оно сохраняет ваши изменения. Если они удалили файл, который вы не касались, или удалили строку из файла, который вы не коснулись, git сохраняет их изменения. Если вы оба сделали точно такой же изменить на weather.h, git держит один экземпляр этого изменения (а не двух экземпляров). Git применяет все «сохраненные» изменения к базовой версии и записывает результат в ваше рабочее дерево, а слияние теперь выполняется без конфликтов слияния. Результат, по мнению git, готов к совершению. (Обратите внимание, что это верно, даже если некоторые изменения, которые вы сделали, требуют, скажем, чтобы система сохраняла удаленный файл, который git теперь удалил. То есть предположим, что они сказали: «О, смотрите, этот файл не используется, давайте уберем его »и вы сказали:« О, oops, я забыл использовать этот файл, давайте использовать его ». Git не знает, что эти изменения действительно конфликтуют: все, что он может сказать, это то, что строки в diff don ' t сталкиваются.)

    Следующий шаг зависит от того, был ли вы задан флаг --no-commit. Это подавляет фиксацию, несмотря ни на что. Если вы не подавляли фиксаций, git merge совершает это множество не-очевидно-конфликтных изменений, как «слияние совершить», который имеет два родителей:

       o - A ----- M <-- your branch (master) 
          /  /
    ... - o - B   /
          \  /
           o - o - C <-- their branch (origin/master) 
    

    На данный момент, рабочее дерево соответствует новой фиксации M. Пока он не был проверен , было проверено в (совершено) как слияние.

    Если вы сделали, скажите --no-commit, или если произошел конфликт слиянием, слияние прекратится и вы сможете исправить и/или совершить слияние. Изменения просто присутствуют в вашем рабочем каталоге. Если и когда вы решите зафиксировать результат, это будет слияние. Гит знает это, потому что он оставляет файл трассировки, говорящий «в середине слияния». Если вы решили отменить слияние с git merge --abort, это приведет к удалению трассировочного файла.

  • Для перестановки git проходит аналогичный процесс. Однако вместо того, чтобы найти базу слияния, он находит набор коммитов, которые у вас есть, что нет. Мы можем сделать эту схему еще раз, но давайте использовать различные имена узлов:

       A - B  <-- your branch (master) 
          /
    ... - o - o 
          \ 
           C - D - E <-- their branch (origin/master) 
    

    В этом случае мерзавец находит ваши два фиксаций (A и B) и копии их (с помощью git cherry-pick, более или менее). Механизм для этого потенциально сложный, поэтому давайте просто отметим здесь, что каждая операция cherry-pick требует обновления вашего рабочего дерева и создания нового коммита. Если все пойдет хорошо, мы вышлем копию A, A' и копию BB'; git перемещает название ветки, указывая на B'; и окончательный рисунок выглядит следующим образом:

       A - B  [abandoned] 
          /
    ... - o - o    A' - B' <-- your branch 
          \   /
           C - D - E <-- their branch 
    

    Поскольку каждый шаг вишневого драфта обновляет рабочее дерево и делает коммит из нее, ваша работы дерево соответствует окончательному обязательству B', не потому, что он получил проверило из, но потому, что он был проверен в (совершенный), точно так же, как в случае слияния.

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

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

    Хорошо, что вы можете иногда производить слияние, даже если слияние с чистой деревом не получится. Плохая вещь в этом заключается в том, что это действительно легко сделать это случайно, когда вы этого не хотели, и завершайте своими изменениями, собранными вместе с их изменениями, и очень трудно отступить. Как правило, это просто плохая идея: commit или stash, а затем слиться из чистого состояния, возможно, с --no-commit, если хотите.Затем вы можете запускать тесты и выполнять свою собственную фиксацию после каких-либо исправлений. (Обратите внимание, что вы также можете использовать git commit --amend при фиксации слияния.)

  • Для переустановки обычно git rebase просто откажется запускать, если дерево дерева не будет чистым. Это делает это легким делом. Однако, поскольку git 1.8.4, rebase теперь имеет настраиваемую настройку rebase.autostash. Если вы установите это значение, ваш rebase будет запускать git stash для вас в этом случае, а затем выполнить rebase, а затем (если все будет хорошо) вытащите кошелек для вас. У этого режима есть раздражающая (но не смертельная) ошибка, которая не была зафиксирована до git 2.0.1, и я рекомендую против нее в целом - я думаю, что лучше всего сделать фиксацию контрольной точки и очистить ее на более позднем сеансе очистки (обычно бывает полезно пройти очистку до того, как «финализация» совершит, и настало время отбросить временные контрольно-пропускные пункты, и до тех пор они естественным образом перестраиваются, без какой-либо опасности скребковых автозапуска).


Хотя диаграмма говорит «время увеличивается вправо», технически это действительно просто, что узлы справа являются преемниками их узлов слева. Это особенно актуально, когда вы получаете фиксации с удаленного. Временные метки в этих коммитах были сделаны на каком-то другом компьютере, и даже если вы хорошо разбираетесь в том, что ваш собственный компьютер синхронизирован с атомными часами где-то, кто знает, что их часы являются/были/правильными? Эти метки времени могут быть полностью сломаны. Заказ времени не гарантируется, просто «вероятен».

Кроме --no-commit, git merge также принимает --squash флага, который имеет два побочных эффектов: (1) окончательная фиксация не слияние фиксации на всех, и (2) после выполнения все обычной работы для слияния, git merge останавливается без фиксации (как и для --no-commit). То есть, что --squash делает внутренне, чтобы остановить окончательный фиксатор и stop git merge от записи этого специального файла состояния, который сообщает git, что он находится в середине слияния. Таким образом, инструкция, которую вы должны выполнить после этого, представляет собой обычную фиксацию без объединения.

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