Я думаю, ваша основная проблема здесь в том, что вы неверно истолковываете и / или не понимаете, что делает git и почему он это делает.
Когда вы клонируете какой-либо другой репозиторий, git делает копию того, что находится «там». Он также берет «свои» метки веток, такие как master
, и делает копию той метки, чье «полное имя» в вашем дереве git (обычно) remotes/origin/master
(но в вашем случае remotes/upstream/master
). В большинстве случаев вы можете опустить и эту remotes/
часть, поэтому вы можете ссылаться на эту оригинальную копию как upstream/master
.
Если вы сейчас внесете и зафиксируете некоторые изменения в каком-то файле (файлах), вы единственный, кто внесет эти изменения. Тем временем другие люди могут использовать исходный репозиторий (из которого вы создали свой клон) для создания других клонов и изменения этих клонов. Конечно, только они со своими изменениями. В конце концов, у кого-то могут быть изменения, которые они отправляют обратно первоначальному владельцу (с помощью "push", патчей или чего-то еще).
Команда git pull
в основном является сокращением от git fetch
Follow git merge
. Это важно, потому что это означает, что вам нужно понимать, что на самом деле делают эти две операции.
Команда git fetch
говорит вернуться туда, откуда вы клонировали (или иным образом настроили как место для извлечения), и найти «новые вещи, которые кто-то добавил, изменил или удалил». Эти изменения копируются и применяются к вашей копии того, что вы получили от них ранее . Они не применяются к вашей собственной работе, только к их.
Команда git merge
более сложная, и вы ошибаетесь. Что он делает, немного упрощенно, - это сравнивает «то, что вы изменили в своей копии», с «изменениями, которые вы получили от кого-то другого и, таким образом, были добавлены в вашу копию чужой-работы». Если ваши изменения и их изменения не конфликтуют, merge
операция объединяет их вместе и дает вам «фиксацию слияния», которая связывает вашу разработку и их разработку вместе (хотя есть очень распространенный «простой» случай, когда у вас нет меняется и вы получаете "перемотку вперед").
Ситуация, с которой вы сейчас сталкиваетесь, - это та, в которой вы внесли изменения и зафиксировали их - фактически девять раз, отсюда «впереди 9» - и они не внесли никаких изменений. Итак, fetch
послушно ничего не получает, а затем merge
принимает их отсутствие изменений и тоже ничего не делает.
Вы хотите посмотреть или, может быть, даже "сбросить" до "их" версию кода.
Если вы просто хотите взглянуть на него, вы можете просто проверить эту версию:
git checkout upstream/master
Это говорит git, что вы хотите переместить текущий каталог в ветку, чье полное имя действительно remotes/upstream/master
. Вы увидите их код на момент последнего запуска git fetch
и получения последнего кода.
Если вы хотите отказаться от всех собственных изменений, вам нужно изменить представление git о том, какую ревизию master
должен называть ваш ярлык . В настоящее время он называет вашу самую последнюю фиксацию. Если вы вернетесь в эту ветку:
git checkout master
тогда git reset
команда позволит вам как бы "переместить метку". Единственная оставшаяся проблема (при условии, что вы действительно готовы отказаться от всего, что делали) - это найти, куда должна указывать этикетка.
git log
позволит вам найти числовые имена - такие вещи, как - 7cfcb29
которые являются постоянными (никогда не меняющимися) именами, и есть смехотворное количество других способов назвать их, но в этом случае вам просто нужно имя upstream/master
.
Чтобы переместить метку, удалив свои собственные изменения (все, что вы зафиксировали, на самом деле можно восстановить в течение некоторого времени, но после этого будет намного сложнее, поэтому будьте очень уверены):
git reset --hard upstream/master
--hard
Рассказывает мерзавец , чтобы уничтожить то , что вы делаете, переместить текущую метку ветви, а затем проверить данное обязательство.
Это не очень распространенное явление - действительно захотеть git reset --hard
и уничтожить кучу работы. Более безопасный метод (значительно упрощающий восстановление этой работы, если вы решите, что некоторые из них в конце концов стоили) - переименовать существующую ветку:
git branch -m master bunchofhacks
а затем создайте новую локальную ветку с именем, master
которая «отслеживает» (мне не очень нравится этот термин, поскольку я думаю, что он сбивает людей с толку, но это термин git :-)) исходный (или восходящий) мастер:
git branch -t master upstream/master
с которыми вы можете заняться:
git checkout master
Что делают последние три команды (есть ярлыки, чтобы сделать это всего лишь двумя командами), так это изменить имя, вставленное в существующую метку, затем создать новую метку, а затем переключиться на нее:
прежде чем что-либо делать:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "master"
после git branch -m
:
C0 - "remotes/upstream/master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
после git branch -t master upstream/master
:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 --- C8 --- C9 "bunchofhacks"
Вот C0
последний коммит (полное дерево исходных текстов), который вы получили, когда впервые сделали свой git clone
. С C1 по C9 - ваши коммиты.
Обратите внимание, что если бы вы сделали git checkout bunchofhacks
и затем git reset --hard HEAD^^
, это изменило бы последнее изображение на:
C0 - "remotes/upstream/master", "master"
\
\- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 - "bunchofhacks"
\
\- C8 --- C9
Причина в том, что HEAD^^
имя ревизии два выше заголовка текущей ветки (которая была бы непосредственно перед сбросом bunchofhacks
), а reset --hard
затем перемещает метку. Коммиты C8 и C9 теперь в основном невидимы (вы можете использовать такие вещи, как reflog, и git fsck
находить их, но это уже не тривиально). Ваши ярлыки принадлежат вам, чтобы перемещать их как хотите. Команда fetch
позаботится о тех, которые начинаются с remotes/
. Принято сопоставлять «ваш» с «их» (так что, если у них есть, remotes/origin/mauve
вы бы mauve
тоже назвали свое ), но вы можете ввести «их», когда захотите назвать / увидеть коммиты, которые вы получили «от них». (Помните, что «одна фиксация» - это все дерево исходных текстов. Вы можете выбрать один конкретный файл из одной фиксации, git show
например,