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

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

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

git pull upstream master

для извлечения и объединения из восходящего потока (так что теоретически, что удаленный код должен быть обратно).

Git говорит мне, что все в актуальном состоянии.

Все, безусловно, НЕ обновлено - все, что удаленный код все еще удаляется.

Другая релевантная информация

У меня есть только одна ветвь с именем "master".

Недавно я установил "master" для отслеживания вверх по потоку, например:

Филиал ветки настроен для отслеживания мастера удаленных веток вверху.

Команда git branch -vv дает:

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

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

Update

Я думал, что это очевидно, но в любом случае это моя цель:

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

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

Ответ 1

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

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

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

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

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

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

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

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

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

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 уничтожить то, что вы делали, переместите текущую метку ветки и затем проверите данную фиксацию.

Это не супер-общее, чтобы действительно хотеть 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. С1 по С9 - ваши коммиты.

Обратите внимание, что если бы вы были git checkout bunchofhacks, а затем git reset --hard HEAD^^, это изменило бы последнее изображение на:

C0 -    "remotes/upstream/master", "master"
    \
     \- C1 --- C2 --- C3 --- C4 --- C5 --- C6 --- C7 -    "bunchofhacks"
                                                      \
                                                       \- C8 --- C9

Причина в том, что HEAD^^ называет ревизию два от главы текущей ветки (которая непосредственно перед reset будет bunchofhacks), а reset --hard затем перемещает метку. Commits C8 и C9 теперь в основном невидимы (вы можете использовать такие вещи, как reflog и git fsck, чтобы найти их, но это уже не тривиально). Ваши ярлыки ваши, чтобы двигаться, как вам нравится. Команда fetch заботится о тех, которые начинаются с remotes/. Это условно, чтобы соответствовать "вашим" с "их" (так что если у них есть remotes/origin/mauve, вы бы назвали ваш mauve тоже), но вы можете набирать "их", когда хотите называть/видеть, что у вас есть "от них". (Помните, что "одно коммит" является целым деревом источника. Вы можете выбрать один конкретный файл из одного коммита с помощью git show, например, если и когда вы этого хотите.)

Ответ 2

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

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

Ответ 3

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

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

Update:

ПОЛУЧИТЕ САМОЕ ПОСЛЕДНИЕ КОДА НА МОЮ СИСТЕМУ

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

git fetch upstream
git checkout upstream/master

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

Ответ 4

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

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

Как сказал Райан, я предлагаю вам точно указать, в чем заключается ваша цель, чтобы кто-то мог помочь вам более непосредственно.

Ответ 5

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

  • Переключиться на мастер

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

    $ git branch -d <branch_name>
    
  • Создайте новую ветку

    $ git checkout -b <new_branch_name>