Git: как двигаться вперед и назад между фиксациями
У меня есть вопрос новичков о Git:
Мне нужно двигаться вперед и назад в истории ветки.
Это означает, что мне нужно получить все файлы в состоянии, в котором они находились, в какой-то старой версии, а затем мне нужно вернуться в последнее состояние в репозитории. Мне не нужно фиксировать.
С SVN это будет
svn up -r800
чтобы перейти к редакции 800, и
svn up
чтобы синхронизировать с репозиторием.
Я знаю хэш коммита, к которому я хочу вернуться, поэтому я попробовал
git reset <hash>
который, кажется, доставит меня туда. Но потом я попробовал
git pull
но он жалуется на конфликты.
Итак, каков правильный способ перемещения по истории ветки?
Я думаю с точки зрения SVN, так что не стоит его указывать на хороший учебник. Обратите внимание, что я уже проверил http://git.or.cz/course/svn.html и http://www.youtube.com/watch?v=8dhZ9BXQgc4.
Спасибо, Ондра.
Ответы
Ответ 1
Ну, я тоже бывший пользователь svn, и теперь использую git для всех моих проектов.
При использовании git вы должны изменить способ мышления из архитектуры клиент-сервер, которая используется в svn. В svn для каждого изменения требуется соединение с сервером. Используя git, ваше репо находится в рабочем каталоге. Вам не нужно подключение для каждого действия репо.
Используйте только git push
и git pull
для синхронизации с репо. Подумайте, как использовать rsync или любое решение для резервного копирования, чтобы сделать два места одинаковыми. Так же, как вы подключаете внешний жесткий диск резервного копирования, затем сделайте содержимое в нем тем же самым с содержимым в вашем главном. Это использование git pull
и git push
.
Если вы просто хотите вернуться назад и вперед по истории, сделайте это, используя git checkout
. См. Идентификатор ревизии с помощью git history
. Если вы используете Linux, используйте gitk
, чтобы увидеть дерево изменений. В Windows черепаха git может отображать его с помощью графика изменений.
Чтобы вернуться к последней версии, используйте git checkout master
. Перед выполнением любой команды всегда делайте git status
. Эта команда отобразит все, что вам нужно знать о текущем состоянии репо, и о том, какие действия вам нужно сделать, чтобы сделать это правильно. Прежде чем git pull
и git push
, лучше убедиться, что результат git status
содержит текст working directory clean
.
Если вам нужно вернуть файл к предыдущей версии, вы можете сделать это с помощью git merge
. Прежде чем делать это с файлом, сначала проверьте его с помощью git diff
. Пример: git diff rev1:rev2 filename
. Он будет распечатывать любые изменения между двумя версиями. Изменение в rev1 будет заменено на изменения rev2. Поэтому, чтобы вернуться, rev2 будет старше, чем rev1. После того, как вы удовлетворите результатом diff, сделайте это с помощью git merge
, просто замените diff
на merge
, все остальные параметры останутся прежними.
Надеюсь, это поможет вам. Основной ключ - увидеть, что ваш рабочий реестр - это ваше репо. Понимание этого поможет вам полностью использовать git. Удачи.
Ответ 2
Вы можете использовать git checkout
для проверки любой фиксации, а затем использовать ее с именем ветки, чтобы вернуться к именованной ветке.
git checkout
с идентификатором фиксации, а не именем ветки, вы отключаете какую-либо именованную ветвь и на то, что известно как отсоединенная головка.
Если вы используете git reset
, тогда он переместит вашу ветку обратно в старое состояние, выйдя из строя более поздние коммиты, которые, вероятно, не то, что вы хотите.
Ответ 3
Другие ответы носят информативный характер, но я считаю, что это ближе всего к тому, что хочет OP:
Добавьте эти две функции в ваш ~/.bashrc:
# checkout prev (older) revision
git_prev() {
git checkout HEAD~
}
# checkout next (newer) commit
git_next() {
BRANCH=`git show-ref | grep $(git show-ref -s -- HEAD) | sed 's|.*/\(.*\)|\1|' | grep -v HEAD | sort | uniq`
HASH=`git rev-parse $BRANCH`
PREV=`git rev-list --topo-order HEAD..$HASH | tail -1`
git checkout $PREV
}
Использование:
$ git_prev
Previous HEAD position was 7042c8a... Commit message2
HEAD is now at d753ecc... Commit message1
$ git_next
Previous HEAD position was d753ecc... Commit message1
HEAD is now at 7042c8a... Commit message2
Примечание. Эти команды всегда входят в состояние отсоединенного HEAD. Если вы git_prev
, а затем git_next
из текущей проверенной ветки, вы вернетесь к последней версии, но вы будете в состоянии автономного состояния HEAD. Сделайте git checkout BRANCH_NAME
, чтобы вернуться к нормальной работе.
Ответ 4
Чтобы проверить другую версию файла, используйте
git checkout rev -- filename
Где rev может быть идентификатором фиксации, именем ветки, именем тега или относительной версией.
Используйте git log
, gitk
, чтобы просмотреть проверенные версии, чтобы посмотреть, какую версию файла вы хотите.
Чтобы сделать эту версию файла постоянной, вам необходимо зафиксировать файл: git add filename; git commit filename
Я бы не рекомендовал git pull
проверять версии, потому что он выполняет слияние - потенциально изменяя ваше текущее состояние.
В этом случае вам не нужно использовать git reset
, если вы не git add
файл, который вы решили не совершать.
Ответ 5
Попробуйте git reflog
, в этом списке перечислены и сделанные вами проверки для переключения между фиксациями, даже те коммиты, которые вы потеряли, когда выходите на предыдущую фиксацию.
Затем вы можете попробовать git checkout <hash of a commit>
переключиться на эту фиксацию.
Надеюсь, это поможет!