LINUX.ORG.RU

GIT почему-то влепил коммит в середину истории. Теперь не могу откатиться.


0

1

Ох, не любит меня Git.

Сейчас произошло нечто, что выше моего понимания. Всегда делаю коммит и заливку в репозитарий командами:

git add . 
git commit -a 
git push

У меня, по большей части, все линейно. Есть всего две ветки - master и try_django. Ветка try_django - это тупиковая ветка (была раньше тупиковой), и должна была остаться тупиковой.

Картинка:

http://i.piccy.info/i9/7e33e6eee876e90a8a2425c8480d95ae/1385497698/73131/5974...

При последнем коммите 27.11.13 0:02 вылезло предупреждение, что что-то не так (я особенно не понял), и предложение сделать git pull:

 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:xintrea/local_rash.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Я сделал git pull, он завершился ошибкой:

Renaming apprash/config/config.php => misc/06_linuxthash_php/apprash/config/config.php
Auto-merging misc/06_linuxthash_php/apprash/config/config.php
CONFLICT (rename/modify): Merge conflict in misc/06_linuxthash_php/apprash/config/config.php
CONFLICT (rename/delete): Rename css/main.css->misc/06_linuxthash_php/css/main.css in 081262b214d515aba563ded9dc8eeb9ff0896cc6 and deleted in HEAD
Renaming index.php => misc/06_linuxthash_php/rash.php
Auto-merging misc/06_linuxthash_php/rash.php
Removing data/base/db_20120901172549.sqlite
Removing data/pic/team_avatar/0157a760f5710c2d92f44bb5e6f49817.png
Removing data/pic/team_avatar/c11f8869892fa7462b9970e2f29d87c6.png
Removing data/pic/team_avatar/team_avatar_avangard.png
Removing data/pic/team_avatar/team_avatar_dinamo.png
Removing data/pic/team_avatar/team_avatar_ksov.png
Removing data/pic/team_avatar/team_avatar_spartak.png
Removing data/pic/trainer_avatar/3f7ca692c08f26d11c339e84f5c1809e.png
Removing data/pic/trainer_avatar/eff8e5e721d198a4cc2addc965df5b8d.png
Removing main.html
Automatic merge failed; fix conflicts and then commit the result.

Тогда я снова сделал «три команды». Git что-то сказал про merge (причем, я прямой команды на merge не давал!):

[master c3e8a45] Merge branch 'master' of bitbucket.org:xintrea/local_rash
Counting objects: 50, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (30/30), done.
Writing objects: 100% (34/34), 4.09 KiB, done.
Total 34 (delta 19), reused 0 (delta 0)
To git@bitbucket.org:xintrea/local_rash.git
   081262b..c3e8a45  master -> master

И результат вы видите на картинке - коммит 27.11.13 0:09 со слиянием, которое мне никуда не впало.

Видно, что коммит 27.11.13 0:02 находится в середине истории (почему???), ПОСЛЕ более ранних коммитов.

Теперь задача: мне нужно к этому коммиту (27.11.13 0:02) вернуться.

И я не могу это сделать!

Пробую:

git checkout a906f16ce7147911e9f950d569f2aeeb51091970

где a9...70 - это ID коммита 27.11.13 0:02.

Не помогает, я не вижу файлов которые я делал при этом коммите.

Пробую:

git reset --soft a906f16ce7147911e9f950d569f2aeeb51091970

Такая же фигня, состояние не возвращается к состоянию, в котором находился проект при коммите 27.11.13 0:02.

Вопрос: Как вернуться к состоянию, которое было при коммите 27.11.13 0:02?

Вот история коммитов (git log) ветки master, если поможет. Сейчас в ней почему-то нет финального коммита 27.11.13 0:09, хотя на картинке он виден. Может быть это из-за git reset.

$ ./git_log.sh
commit a906f16ce7147911e9f950d569f2aeeb51091970
Author: xintrea <xintrea@gmail.com>
Date:   Wed Nov 27 00:02:45 2013 +0400

    - Добавлен начальный двухколоночный макет главной страницы

commit e99bd9cc6df72e57632064db849b31ac5cb3830a
Author: xintrea <xintrea@gmail.com>
Date:   Sun Nov 17 18:35:46 2013 +0400

    - Первый коммит после отката от Django

commit 0e7b5221595c44be888b27b980ab45c6ea2dde25
Author: xintrea <xintrea@gmail.com>
Date:   Tue Sep 4 23:12:02 2012 +0400

    Сделан перенос обнаруженных удаленных новостей в базу публикаций
    в раздел новостей

commit 577d9b379d12e51e87c25b24d2a53ceb72568f44
Author: xintrea <xintrea@gmail.com>
Date:   Sat Sep 1 10:53:36 2012 +0400

    Подготовлен скрипт lorpad, он начал наполнять базу 

commit 7a0757665ad7821342f1a221bae5d791e110cfa1
Author: xintrea <xintrea@gmail.com>
Date:   Mon Aug 27 01:25:30 2012 +0400

    Почти рабочий вариант с самодельным SQLite3 драйвером sqlite3pdo

commit 632f20b66ee8d9468732161ca1f210db1f79edce
Author: xintrea <xintrea@gmail.com>
Date:   Sun Aug 19 01:14:31 2012 +0400

    Сделан переход на CodeIgniter 2.1.2
    Исправлен PDO драйвер чтоб можно было работать с SQLite базой
    Заведена пробная база news
    Хранение сессий в базе данных временно отключено

commit 2b90796b230d31428c24d215a6ecbb28a7c2e0f0
Author: xintrea <xintrea@gmail.com>
Date:   Fri Aug 17 21:59:48 2012 +0400

    Заменен CodeIgniter Debug Tool bar на более свежую версию, взятую
    с github. Для установки пришлось изменить только конструктор в MY_Log.php
    Этот вариант показывает используемые файлы.

... 
★★★★★

git add .
git commit -a
git push

Кстати, почему он такой многословный? После привычных hg ci && hg push вводить это регулярно задалбывает…

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Кстати, почему он такой многословный? После привычных hg ci...

Охх...

git config alias.ci '!sh -c "set -e; if test $# -eq 0; then git add -u; else git add "$@"; fi; git commit"'

Соль и перец по вкусу.

Надеюсь, не облажался в кавычках. Если облажался, или если хочется навернуть сильно больше логики по разбору параметров, то можно реализовать честным скриптом в /usr/libexec/git-core. Но, как Вы понимаете, это остаётся в качестве упражнения читателю.

AlexM ★★★★★
()
Последнее исправление: AlexM (всего исправлений: 2)
Ответ на: комментарий от Deleted

git add -u воспроизводит поведение SVN, более-менее. Ну, ради тех, кому хочется почувствовать себя вернувшимся на 10 лет назад :) Тогда, поди, и гемо радикулит не так часто мучал, и вообще девушки вокруг были моложе.

AlexM ★★★★★
()
Последнее исправление: AlexM (всего исправлений: 2)
Ответ на: комментарий от Deleted

Настрой алиасы в .gitconfig. И дождёшься таки, чтобы руки оторвали тебе за коммиты всего и вся.

Ну только если я сам себе их оторву, ибо я единственный разработчик.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от AlexM

Ну в общем, восстановил состояние на нужный мне коммит. Локально восстановил, естественно. Пришлось создать restore-ветку, в ней экспериментировать.

Теперь надо понять, как это состояние залить на сервер, чтобы не напороться по второму разу на те же грабли.

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

Поэтому сейчас стоит вопрос: по какому пути пойти? Разбираться, как заливать только ветку, или разбираться, как заливать данные для получения полного зеркала на сервере.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

git branch -v master shit *recovery

git branch -D master git branch -m master git push -f origin master

anonymous
()
Ответ на: комментарий от Xintrea

ну, для начала просто попробовать

git push <remote-server> -f master

(<remote-server> - это обычно origin, но вообще при помощи git remote можно вывести весь список и управлять им, если надо)

В зависимости от настроек удалённого сервера эта команда (принудительное переписывание ветки master) может сработать, а может и нет. «Заборонено, см. рис. 1». Если forced push не удался, то можно попробовать удалить ветку master в удалённом репозитории вовсе:

git push <remote-server> :master

(в этом случае мы отправляем пустой референс в master на <remote-server>, что эффективно удаляет его). После этого можно заливать текущий локальный master обычным способом.

Если же и второй способ не сработал («здравствуй, Gerrit!» :) ), то можно попытаться удалить ветку master через web-интерфейс удалённого сервера. Я почему так уверенно говорю про web-интерфейс: «обычные» git-сервера с настолько жестокими настройками по манипулированию ветками если и существуют, то наверняка там есть внешняя, нестандартная система управления правами, которая обычно доступна через web.

AlexM ★★★★★
()
Ответ на: комментарий от anonymous

Хочу обратить внимания на то, что данная команда

git branch -D master
удалит локальную ветку master. Ничего непоправимого [сразу] от этого не произойдёт, есть git reflog, но хочется напомнить, что такие операции следует проводить на трезвую и холодную голову :)

AlexM ★★★★★
()
Ответ на: комментарий от AlexM

но вообще при помощи git remote можно вывести весь список и управлять им, если надо

Весь список чего?

Если forced push не удался

Блин, о форсед пуш речи выше по тексту не идет.

в этом случае мы отправляем пустой референс

Что есть референс?

После этого можно заливать текущий локальный master обычным способом

Обычным - это каким?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Весь список чего?

список сконфигурированных удалённых репозиториев. В каждом локальном репозитории может отслеживаться состояние нескольких удалённых. Для этого информацию о их местонахождении заносят в .git/config либо при промощи команды git remote, либо текстовым редактором. Команда git remote --help , как и все остальные команды git, показывает релевантную страничку man. Попробуйте её прочесть, чтобы мне не было нужды пересказывать её Вам.

Блин, о форсед пуш речи выше по тексту не идет.

push -f (== push --force) - это как раз forced push.

Что есть референс?

reference. ссылка. См. выше мой рассказ про то, что ветки в git - это метки. Теги, кстати, тоже метки. Просто они не двигаются туда-сюда, и у них есть режим с GPG-подписью и прочими атрибутами, более сложный, чем просто запись в .git/refs/tags.

Обычным - это каким?

git push <remote> master

без ключика --force

Вообще, повторюсь, у каждой git'овой команды есть соответствующая ей страничка man. Добывается при помощи ключика --help . Не стесняйтесь ей пользоваться.

AlexM ★★★★★
()
Последнее исправление: AlexM (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.