.git: получение и применение коммитов удаленной ветви
У меня есть некоторые старые изменения, которые я сделал, зафиксировал и отправил в удаленное (bitbucket) РЕПО. Эти изменения не были объединены ни с одной другой ветвью. Сама ветка была удалена локально и из удаленного РЕПО.
Но, как я вижу в bitbucket web, коммиты, включенные в удаленную ветку, все еще там (в репо). Я много гуглил, но так и не нашел способа, как восстановить фиксация удаленной ветки с пульта дистанционного управления. Единственное, что я могу сделать, это увидеть их в bitbucket web и получить ша из commit там.
Я видел некоторые примеры, такие как
git checkout <sha>
Или
git checkout -b <branch-name> <sha>
Но всегда получаем следующую ошибку
fatal: reference is not a tree: <sha>
Итак, возможно ли и как я могу извлечь (fetch) эти коммиты из удаленного, обрешетить ветку от них, слить в release ветку?
UPD:
Если быть более точным, я создал РЕПО, новую ветку, сделал коммит в этой ветке ne и удалил ветку:
РЕПО https://github.com/yurybond/stackowerflow-rocks
По ссылке (автономное) совершение от удаленная ветка https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84
Вопрос все тот же: как восстановить commit (a1c1540abd453773b3ce6445d01e51ad336bbe84), который принадлежит удаленной ветви?
6 ответов:
Вы можете вручную загрузить недостающие файлы. коммиты в формате
mbox
и применять их вручную с помощьюgit am
. Для пример:
github
(репозиторий, на который вы ссылаетесь):$ wget https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84.patch && git am a1c1540abd453773b3ce6445d01e51ad336bbe84.patch
gitlab
:$ wget https://git.weboob.org/weboob/devel/commit/bba7e1b8ffb0743b57f202cf9cdb43fda209fa43.patch && git am bba7e1b8ffb0743b57f202cf9cdb43fda209fa43.patch
bitbucket
:$ wget https://bitbucket.org/Kasreyn/linux-3-9-rc3-moxart/commits/434e8f69db2c3effdc8741139adb722a68dfcccd/raw -O 434e8f69db2c3effdc8741139adb722a68dfcccd.patch && git am 434e8f69db2c3effdc8741139adb722a68dfcccd.patch
Обратите внимание, что
git am
не только применит текстовый патч, но и воссоздайте всю фиксацию в текущей ветке.Если вы удалили ветку из удаленного репозитория, то это невозможно сделать. получить его вернулся из удаленного хранилища. Тем не менее, обычно вы все еще возможно, удастся восстановить удаленную ветвь локально благодаря
git reflog
. Увидеть следующее образец.Во-первых, создайте новый не-голый репозиторий:
$ git init Initialized empty Git repository in /tmp/reflog-test/.git/
Добавьте
file
и создайте новый коммит на веткеmaster
:$ touch file $ git add . $ git commit -m 'Initial commit' [master (root-commit) 81fc76d] Initial commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file
Переключиться на новую ветвь с творческим названием
new-branch
:$ git checkout -b new-branch Switched to a new branch 'new-branch'
Изменить
file
и зафиксировать изменения:$ echo new-branch >> file $ git commit -am 'commit on new-branch' [new-branch 9c457c6] commit on new-branch 1 file changed, 1 insertion(+)
Переключиться обратно на
master
:$ git checkout - Switched to branch 'master' $ git branch * master new-branch
Удалить
new-branch
$ git branch -D new-branch Deleted branch new-branch (was 9c457c6).
Его больше нет:
$ git branch * master $ git log new-branch fatal: ambiguous argument 'new-branch': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'
Однако вы все равно должны иметь возможность ссылаться на фиксацию:
$ git show --stat 9c457c6 commit 9c457c69de8a54376a2614ca8cfc0f515c64676c Author: Arkadiusz Drabczyk <adrabczyk@bigcorp.com> Date: Tue Apr 3 10:43:49 2018 +0200 commit on new-branch file | 1 + 1 file changed, 1 insertion(+)
, хотя он не может быть найден на любом отделении. Следующая команда ничего не возвращает:
$ git branch --contains 9c457c6
Reflog
показывает все действия, выполненные в репозитории:$ git reflog dbc721a HEAD@{0}: checkout: moving from new-branch to master 9c457c6 HEAD@{1}: commit: commit on new-branch dbc721a HEAD@{2}: checkout: moving from master to new-branch dbc721a HEAD@{3}: commit (initial): Initial commit
Как вы видите, он также имеет
9c457c6
фиксацию, которую мы сделали наnew-branch
. Только когда истекает срок действияreflog
и запускается сборщик мусора9c457c6
становится недостижимым:$ git reflog expire --expire=all --all $ git gc --prune=now Counting objects: 3, done. Writing objects: 100% (3/3), done. Total 3 (delta 0), reused 0 (delta 0) $ git show 9c457c6 fatal: ambiguous argument '9c457c6': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]'
По умолчанию
reflog
записи истекают через 90 дней иgit gc
выполняется автоматически после некоторых команд, так что если вы удалили ветку относительно недавно вы должны быть в состоянии восстановить его.
Если этот коммит действительно существует в репозитории Bitbucket, то вы можете объединить его в другую ветвь с помощью веб-интерфейса Bitbucket.
- перейдите в раздел ветви -- > создайте новую ветвь в Bitbucket. Назовите его как хотите
- Когда ветвь будет создана, нажмите кнопку Сравнить (меню три точки в правом верхнем углу)
- на экране сравнения выберите Изменить источник и вставьте ссылку на фиксацию. Если это приведет к результату, то вам повезло. Выбрать оно.
- выберите пункт изменить назначение и измените его на новую ветвь.
- Вы должны иметь возможность просматривать разницу, видя все изменения, которые вы хотите внести.
- Выберите объединить, если вы счастливы.
Теперь вот Кикер. Если вставить ссылку на фиксацию на Шаге 3 не удается, значит, вам не повезло. Это означает, что фиксация не существует ни на удаленном компьютере, ни в локальном.
Если вы ненавидите навигацию и хотите прямую ссылку на сравнение (будет сравнивать с мастер, однако):
https://bitbucket.org/<user>/<repository>/branches/compare/<commit-reference>..master
Ну, поскольку вы удалили ветку локально, вы не можете восстановить ее с помощью sha-1, как все остальные предлагали.
Также рефлог не работает на удаленной стороне (плюс он также удаляется с удаленной стороны.
Это оставляет вам один из двух вариантов. Либо напишите в службу поддержки Bitbucket, чтобы они восстановили то, что вам нужно.
Или попробуйте предложение Майкла здесь: восстановление удаленной ветки с пульта на Bitbucket (git)
Решение предлагаемые звуки, как это может решить вашу проблему. Пожалуйста, дайте мне знать, как это работает
Я не видел ничего в Stack Overflow о проверке фиксации, которая была удалена. Тем не менее, это должно быть возможно сделать жесткий сброс к удаленной фиксации через:
git checkout -b some_new_branch git reset --hard <SHA-1 of deleted commit>
Это сбросит ветвь
some_new_branch
к удаленному коммиту, и, возможно, этого будет достаточно для вас, чтобы продолжить.Я предполагаю, что удаленные коммиты, которые вы видите в Bitbucket, поступают из рефлога. Если это так, то вы также должны иметь возможность просматривать удаленные коммиты через:
git reflog
Если вы не смотрите ваши удаленные коммиты, тогда это также может объяснить вашу ошибку. В этом случае, если удаленные коммиты действительно существуют только на Bitbucket, вам потребуется какой-то другой способ добраться до них.
Если вы все еще можете видеть коммит в Bitbucket(не в недавнем действии), то коммит все еще доступен из какой-то ветви или какого-то тега. Вы можете запустить
git fetch
, чтобы получить последнюю версию этих ссылок, и этот конкретный коммит также будет загружен, если он не существует в локальном репозитории. Однако Ошибкаfatal: reference is not a tree: <sha>
означает, чтоsha
не является фиксацией. Скорее всего, это капля. Если вы найдете правильный коммит,git checkout <commit>
илиgit checkout -b <branch-name> <commit>
должны работать.
Есть ли в ветке какие-либо теги? Причина, по которой ветвь появится на bitbucket, но не будет извлечена с помощью команды fetch, неясна.
В любом случае, попробуйте
git fetch +refs/*:refs/*
затем посмотрите на файл.git/FETCH_HEAD
и, надеюсь, вы найдете там один из коммитов, которые вы хотите. Если нет, то потребуется дополнительная информация. Я бы также сделал копию вашего текущего репо, чтобы избежать головной боли, которая может возникнуть при принудительном получении удаленного рефпространства.