Git rebase версия без аргумента против версии с одним аргументом

Я прочитал кучу материала по SO и документации по Git, и заметил, что после того, как возиться, я не совсем понимаю:

Допустим, у меня есть следующее состояние и конфигурация после выборки, этап 2 git pull и принудительное обновление произошло на origin / master:

$ git log -2 --oneline
a589c89 foo2
e0e5946 foo

$ git log -2 --oneline origin/master
e0e5946 foo

$ git config branch.master.remote
origin

$ git config branch.master.rebase
true

$ git config branch.master.merge
refs/heads/master

В документе говорится ( https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html)

If <branch> is specified, git rebase will perform an automatic git
checkout <branch> before doing anything else. Otherwise it remains on
the current branch.

If <upstream> is not specified, the upstream configured in
branch.<name>.remote and branch.<name>.merge options will be used

Когда я указываю версию git rebase с одним аргументом, это происходит:

$ git rebase origin/master
Pruned remote csv test branches
Successfully rebased and updated refs/heads/master.

$ git log -2 --oneline
a589c89 foo2
e0e5946 foo

Круто, foo2 все еще существует в моей локальной ветке, как и ожидалось. Теперь сделаем это, что должно быть одним и тем же (неявно), потому что согласно документам, branch.master.remote и branch.master.merge разрешаются как origin / master, как показано выше, если я не интерпретирую вещи неправильно:

$ git rebase
Pruned remote csv test branches
Successfully rebased and updated refs/heads/master.

$ git log -2 --oneline
e0e5946 foo

За исключением того, что foo2 потерян, и мы должны сделать git reset --hard HEAD@{2} восстановить. На самом деле не ожидал этого. Есть идеи, почему у меня здесь другое поведение? И как бы я мог предотвратить потерю foo2 в процессе, не переключая branch.master.rebase на false? Я собираюсь сделать перебаз.

1 ответ

Решение

Разница зависит от вашей конкретной версии Git.

В настоящее время (версии Git выше 2. что-то, я не уверен, что это такое), самое большое отличие в том, что версия с тремя аргументами отключает --fork-point по умолчанию, в то время как версия с двумя аргументами включает его по умолчанию.

Вводя git pull в смесь делает вещи еще сложнее, потому что git pull это здесь --fork-point и более старые версии Git ведут себя намного иначе, чем более новые. В частности, перед --fork-point был свой отдельный вариант, только git pull сделал перебазирование в стиле форк-пойнт. Я сомневаюсь, что это проблема в вашей конкретной версии Git, так как тогда вы не увидите разницу с git rebase origin/master против git rebasebranch.master.* конфигурации, поставляющие <upstream>). По крайней мере, я думаю, что вы не будете.

(Для полноты вы можете показать вывод git config --get-all remote.origin.fetchхотя я ожидаю, что это будет стандартная строка +refs/heads/*:refs/remotes/origin/*.)

Дальнейшее чтение на --fork-point: git rebase документация и git merge-base раздел документации по--fork-point,

Другие вопросы по тегам