.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 7

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.

  1. перейдите в раздел ветви -- > создайте новую ветвь в Bitbucket. Назовите его как хотите
  2. Когда ветвь будет создана, нажмите кнопку Сравнить (меню три точки в правом верхнем углу)
  3. на экране сравнения выберите Изменить источник и вставьте ссылку на фиксацию. Если это приведет к результату, то вам повезло. Выбрать оно.
  4. выберите пункт изменить назначение и измените его на новую ветвь.
  5. Вы должны иметь возможность просматривать разницу, видя все изменения, которые вы хотите внести.
  6. Выберите объединить, если вы счастливы.

Теперь вот Кикер. Если вставить ссылку на фиксацию на Шаге 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 и, надеюсь, вы найдете там один из коммитов, которые вы хотите. Если нет, то потребуется дополнительная информация. Я бы также сделал копию вашего текущего репо, чтобы избежать головной боли, которая может возникнуть при принудительном получении удаленного рефпространства.