Почему Git говорит, что моя главная ветка "уже обновлена", хотя это не так?

Основная Проблема

Я просто удалил весь код из файла в моем проекте и зафиксировал изменение в моем локальном git (специально). Я сделал

git pull upstream master

для извлечения и слияния из upstream (так что теоретически удаленный код должен вернуться).

Git говорит мне, что все обновлено.

все, безусловно, не в курсе-все, что удаленный код по-прежнему удаляется.

Другая Соответствующая Информация

у меня только один ветка называется "Мастер".

недавно я настроил "master" для отслеживания вверх по течению так:

мастер ветвей настроен для отслеживания удаленного мастера ветвей вверх по течению.

команда git branch -vv выходы:

* master 7cfcb29 [upstream/master: ahead 9] deletion test

почему, почему это происходит? Я на грани того, чтобы просто отправить по электронной почте моему менеджеру проекта любые изменения, которые я делаю в нашем коде.

обновление

Я думал, что это очевидно, но в любом случае это мой гол:

получите самый последний код в моей системе.

5 ответов


я думаю, что ваша основная проблема здесь в том, что вы неправильно интерпретируете и/или не понимаете, что делает git и почему он это делает.

когда вы клонируете какой-то другой репозиторий, git делает копию того, что "там". Он также принимает" свои " метки ветвей, такие как master, и делает копию этого ярлыка, чье "полное имя" в код дерево git (обычно)remotes/origin/master (но в вашем случае, remotes/upstream/master). Большую часть времени вы можете опустить remotes/ часть тоже, так что вы можете обратитесь к этой оригинальной копии как upstream/master.

если вы теперь сделаете и зафиксируете некоторые изменения в некоторых файлах, вы единственный, у кого есть эти изменения. Между тем другие люди могут использовать исходный репозиторий (из которого вы сделали свой клон) для создания других клонов и изменения этих клонов. Конечно, они единственные, у кого есть изменения. В конце концов, у кого-то могут быть изменения, которые они отправляют обратно первоначальному владельцу (через "push" или патчи или что-то еще).

в git pull команда в основном просто стенография для git fetch следовал по git merge. Это важно, потому что это означает, что вам нужно понять, что на самом деле делают эти две операции.

на git fetch команда говорит, чтобы вернуться туда, откуда вы клонировали (или иным образом настроили как место для извлечения) и найти "новый материал, который кто-то добавил или изменил или удалил". Эти изменения копируются и применяются к вашей копии того, что вы получили от них ранее. Они не применяется к вашей собственной работе, только к их.

на git merge команда сложнее и там, где вы идете наперекосяк. Что он делает, немного упрощенный, сравнивает "то, что вы изменили в своей копии" с "изменениями, которые вы получили от кого-то другого и, таким образом, добавили к своей копии чужой работы". Если ваши изменения и их изменения, похоже, не конфликтуют,merge операция смешивает их вместе и дает вам "слияние", которое связывает ваши развитие и их развитие вместе (хотя есть очень распространенный " легкий "случай, в котором у вас нет изменений, и вы получаете"быструю перемотку").

ситуация, с которой вы столкнулись сейчас, - это та, в которой вы внесли изменения и совершили их-девять раз, фактически, отсюда "вперед 9" - и они сделали нет изменения. Итак,fetch покорно ничего не приносит, а потом merge принимает их отсутствии изменений, а также ничего не делает.

что вы хотите чтобы посмотреть или, может быть, даже "сбросить" на "свою" версию кода.

если вы просто хотите взглянуть на него, вы можете просто проверить эту версию:

git checkout upstream/master

это говорит git, что вы хотите переместить текущий каталог в ветку, полное имя которой на самом деле remotes/upstream/master. Вы увидите их код с момента последнего запуска git fetch и получил их последний код.

если вы хотите отказаться все ваши собственные изменения, что вам нужно сделать, это идея изменения в Git пересмотра метки master, следует назвать. В настоящее время он называет ваш последний commit. Если вы вернетесь на эту ветку:

git checkout master

тут git reset команда позволит вам "переместить метку", как это было. Единственная оставшаяся проблема (при условии, что вы действительно готовы отказаться от всего, что у вас есть) - найти, куда должна указывать метка.

git log позволит вам найти числовые имена-такие вещи, как 7cfcb29-которые постоянные (никогда не изменяющиеся) имена, и есть смешное количество других способов назвать их, но в этом случае вы просто хотите имя upstream/master.

чтобы переместить метку, стирая свои собственные изменения (любые, которые вы совершили, на самом деле восстанавливаются довольно долго, но после этого намного сложнее, так что очень обязательно):

git reset --hard upstream/master

на --hard говорит git стереть то, что вы делали, переместить текущую метку ветви, а затем проверить дано поручение.

это не супер-общие действительно хотите 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 затем перемещает метку. Совершает С8 и С9 сейчас в основном Невидимый (вы можете использовать такие вещи, как reflog и git fsck найти их, но это уже не тривиально). Ваши ярлыки Ваши, чтобы двигаться, как вам нравится. The заботится о тех, которые начинаются с remotes/. Принято сопоставлять "ваше" с "их" (так что, если у них есть remotes/origin/mauve назови свое mauve тоже), но вы можете ввести "их", когда захотите назвать/увидеть коммиты, которые вы получили "от них". (Помните, что" одна фиксация " - это целое дерево источников. Вы можете выбрать один конкретный файл из одной фиксации с помощью git show например, если и когда вы этого захотите.)


Как говорят другие плакаты, pull объединяет изменения из upstream в ваш репозиторий. Если вы хотите заменить то, что находится в вашем репозитории, на то, что находится в восходящем потоке, у вас есть несколько вариантов. Без обиняков, я бы пошел с

git checkout HEAD^1  # Get off your repo's master.. doesn't matter where you go, so just go back one commit
git branch -d master  # Delete your repo's master branch
git checkout -t upstream/master  # Check out upstream's master into a local tracking branch of the same name

любые изменения, которые вы совершаете, например удаление всех файлов проекта, все равно будут на месте после вытягивания. Все, что делает вытягивание, - это слияние последних изменений из другого места в вашу собственную ветвь, и если ваша ветвь удалила все, то в лучшем случае вы получите конфликты слияния, когда восходящие изменения повлияют на удаленные файлы. Итак, короче говоря, да, все в актуальном состоянии.

Если вы опишите, какой результат вы хотели бы иметь вместо "все файлы удалены", может кто-то может предложить соответствующий курс действий.

обновление:

ПОЛУЧИТЕ САМЫЙ ПОСЛЕДНИЙ КОД В МОЕЙ СИСТЕМЕ

Кажется, вы не понимаете, что у вас уже есть самый последний код, который является вашим. Если вы действительно хотите увидеть самое последнее из чужой работа в master-ветке, просто сделать:

git fetch upstream
git checkout upstream/master

обратите внимание, что это не оставит вас в состоянии немедленно (повторно)начать собственная работа. Если вам нужно знать, как отменить то, что вы сделали, или каким-либо иным образом отменить изменения, внесенные вами или кем-то другим, пожалуйста, предоставьте подробную информацию. Кроме того, подумайте о том, для чего предназначен контроль версий, поскольку вы, похоже, неправильно понимаете его основную цель.


кто-то, пожалуйста, поправьте меня, если я ошибаюсь, но я считаю, что это потому, что ваша ветвь опережает главную ветвь вверх по течению на 9 коммитов. Когда вы делаете тянуть с пульта, у вас уже есть эти изменения, это просто, что вы опережаете их на 9 коммитов. Для тех старых изменений, которые у вас уже есть в вашей истории и впереди на 9 коммитов, нет смысла заменять ваши новые изменения.

Я считаю, что если коммиты в удаленном были новее затем они будут объединены в (по умолчанию, если не указать --rebase) к вашей текущей ветви.


верхний ответ намного лучше с точки зрения широты и глубины предоставленной информации, но похоже, что если вы хотите, чтобы ваша проблема была исправлена почти сразу, и не возражаете против некоторых основных принципов управления версиями, вы могли бы ...

  1. переключиться на master

    $ git checkout upstream master
    
  2. удалить ненужную ветку. (Примечание: он должен иметь-D, а не флаг normal-d, потому что ваша ветвь на много коммитов впереди мастер.)

    $ git branch -d <branch_name>
    
  3. создать новую ветку

    $ git checkout -b <new_branch_name>