Я создал новую ветку в своем удаленном репозитории, которая была клонирована из функциональной ветки, используя:
git clone <url> --branch <feature-branch-name> --single-branch <repo-name>
Теперь мне нужно объединить последние изменения из моей ветки dev
, но я не могу клонировать их в свой существующий локальный репозиторий и не вижу их, когда делаю это git branch
.
Любые идеи о том, как я смогу это сделать?
Пробовал обычное клонирование в существующую директорию стандартным способом и методом --branch dev --single-branch
, но безрезультатно.
ОБНОВЛЕНИЕ, нашел эту простую альтернативу
Создать новое происхождение
git remote add *NewOriginName* *repositoryURL*
затем создайте новую ветку-сироту
git checkout --orphan *myNewBranch*
эта новая ветка не будет иметь коммитов, но все файлы из ветки, с которой вы начали, поэтому вы, вероятно, захотите удалить все файлы в этой новой ветке, затем
git pull *NewOriginName* *branchOfInterestOnRepo* --allow-unrelated-histories
и все, вам может понадобиться новая фиксация в зависимости от файлов, которые вы оставили в новой ветке-сироте.
Это похоже на подмодуль
https://git-scm.com/book/en/v2/Git-Tools-Submodules
Но если вы не хотите сохранять предыдущие коммиты, вы можете просто скачать файлы из нужного вам коммита.
Если вы предпочитаете использовать консоль, путь будет с
git clone -b <branchname> --single-branch <remote-repo-url>
Это не создаст ветку, это доставит файлы в вашу активную ветку, в новый каталог, этот каталог с именем ветки из репозитория
Вы захотите отказаться от одной ветки в своем репозитории. Здесь у вас есть два очевидных пути. Один из вариантов — отменить аспект с одной веткой: см. Как мне «отменить» клон --single-branch? (для которого это будет дубликат этого вопроса). Другой требует, чтобы вы прочитали удаленную документацию git, уделяя особое внимание подкоманде set-branches
с ее подпараметром --add
.
Как только вы это сделаете, запустите git fetch
, затем git checkout branch-name
или git switch branch-name
. Git создаст новую ветку. Или используйте имя удаленного отслеживания origin/branch-name
. Подробнее об именах для удаленного отслеживания см. ниже.
Важно понимать, что ваше базовое предположение здесь несколько неверно:
мой удаленный репозиторий... был клонирован из функциональной ветки [и] я не могу клонировать [
dev
] в свой существующий локальный репозиторий
Плохое предположение здесь заключается в том, что команда git clone
не клонирует ветку. Команда Git git clone
— это своего рода удобная команда, сокращение для запуска шести других команд. Пять из этих шести других команд являются командами Git. Для иллюстрации вот шесть команд в том порядке, в котором они выполняются:
mkdir
(или эквивалент вашей ОС): создает новый пустой каталог или папку (в зависимости от того, какой термин вы предпочитаете). Остальные команды выполняются в этом новом каталоге, хотя после завершения git clone
вам также придется самостоятельно перейти в эту новую папку. (Есть один режим, в котором эта команда пропускается, когда вы сообщаете git clone
о существующем пустом каталоге, который он должен использовать.)
git init
: создает новый пустой репозиторий без коммитов. Репозиторий, в котором нет коммитов, не может иметь никаких ветвей, поэтому у него также нет ветвей.
git remote add origin url
: это добавляет то, что Git называет удаленным, в пустой репозиторий. Пульт — это просто короткое имя — здесь origin
— которое будет содержать несколько вещей. Главное, что он содержит, — это URL-адрес, но он также содержит инструкции для будущих команд git fetch
.
Подкоманда git remote add
может принимать опцию -t
, чтобы указать конкретное имя интересующей ветки. Опция --single-branch
к git clone
добавляет эту опцию -t
. (Подкоманда git remote add
также может использовать имя, отличное от origin
. Использование -o
в git clone
делает это, но мы предполагаем, что вы не использовали -o
и, следовательно, используете имя origin
.)
Любые другие git config
команды, подразумеваемые -c
вариантами git clone
. (Эти параметры -c
должны находиться в правильном месте в аргументах командной строки: некоторые параметры -c
обрабатываются внешним интерфейсом git
, а не командой clone
.) Если вы не использовали такие параметры, git clone
ничего не делает на этом шаге, так как делать нечего.
git fetch origin
(или другое имя, указанное через -o
): это получает коммиты от другого Git, который отвечает на указанный вами URL-адрес. Это не создает никаких имен веток в вашем репозитории. На данный момент в вашем новом репозитории еще нет веток.
git checkout
: это создает одну ветку в вашем новом репозитории. Ветка, которую он создает, — это та, которую вы указали с опцией -b
. Если вы не указали параметр -b
, будет создана ветка, имя которой рекомендовано другим Git.
Если вы используете опцию -n
или --no-checkout
, git clone
пропускает этот шаг.
Итак, используете ли вы --single-branch
или нет, шаг 6 из git clone
создает только одну ветку. У вас есть только одна ветка в этом новом репозитории! Обычный клон копирует все коммиты из исходного репозитория и ни одну из веток, а затем Git создает одну ветку в качестве последнего шага.
То, что делает --single-branch
, — это всего лишь одно, но имеет несколько эффектов. Это из-за того, как работает git fetch
. На шаге 5, когда запускается git fetch
, команда fetch подключается к другому Git и его репозиторию. Другой Git перечисляет все имена своих веток и другие имена. 1 Ваш Git может принять во внимание все эти имена или только некоторые из них (например, только одно имя ветки). Каждое из этих имен также содержит необработанный хэш-идентификатор коммита, и именно эти хэш-идентификаторы, а не имена!, нужны Git. С их помощью Git находит коммиты и другие важные объекты, и с их помощью ваш репозиторий клонирует другой репозиторий.
В любом случае, получив соответствующие коммиты и другие объекты, ваш Git теперь берет имена их веток Git — те, которые они указали, чтобы ваш Git мог найти коммиты — и изменяет их. Ваш Git хранит их — или некоторое выбранное их подмножество, например, ровно одно из них — в вашем собственном репозитории как имена для удаленного отслеживания.
Параметр --single-branch
указывает вашему Git оставить инструкции для fetch
по созданию или обновлению только одного имени удаленного отслеживания, соответствующего одному имени ветки в их Git. По умолчанию, конечно, каждый раз создается или обновляется имя удаленного отслеживания для каждой ветки, которую перечисляет другой Git. Если вы используете git remote
, чтобы добавить больше имен их веток, каждый git fetch
создаст или обновит каждое из этих имен, при условии, что другой Git перечисляет их при каждой выборке. Таким образом, отменив одноветвь или добавив больше имен, вы можете получить свой собственный Git для создания большего количества имен для удаленного отслеживания.
1Данные здесь могут быть мучительно большими — порядка мегабайт — в некоторых репозиториях с десятками тысяч имен веток и тегов, и, следовательно, есть способ ограничить их в последних коммуникационных протоколах Git. Старые Git всегда получают все, и по умолчанию для Git без одной ветки нужно получить все, чтобы все по-прежнему работало правильно, но это означает, что если и на вашем компьютере, и на вашем сервере установлена более новая версия Git, сегодня одноветвевые режимы могут быть весьма полезны в некоторых особых случаях.
Имя ветки — это имя, которое вы придумываете сами, и оно должно иметь для вас какое-то значение. Это просто хранит хэш-идентификатор одного (1) коммита. По определению, этот коммит является последним коммитом в ветке. Это позволяет Git найти этот коммит, а коммиты в Git позволяют Git находить больше коммитов в Git. Найдя последний, Git может найти все коммиты, связанные с этой веткой.
(Это означает, что слово ветвь неоднозначно: относится ли оно к имени, такому как dev
или main
или как-то еще? Или оно относится к набору коммитов, заканчивающихся последним? Ответ один, оба или ни один, в зависимости от того, кто это говорит и что имел в виду, когда говорил.
Имя удаленного отслеживания состоит из имени удаленного — origin
— плюс косая черта, за которой следует исходное имя ветки. 2 Эти имена, как и имена веток, позволяют Git находить коммиты. Но на самом деле это не названия ветвей. Вы можете заметить разницу, потому что:
git checkout somebranch
говорит вам, что вы сейчас находитесь «на» ветке, а git branch
и git status
говорят вам, что вы сейчас on branch somebranch
(используя точную фразу для git status
). Но:
git checkout origin/somebranch
говорит вам, что вы сейчас находитесь в том, что Git называет режимом detached HEAD, а git branch
и git status
показывают, что вы больше не находитесь ни в одной ветке. (Этот режим подходит для просмотра коммитов, но не рекомендуется оставаться в нем для выполнения новой работы. Чтобы выйти из этого режима, запустите git checkout
с именем одной из ваших веток, как показано в выводе git branch
.)
Когда вы просите Git переключиться на ветку с именем B
, Git сначала проверяет, есть ли у вас ветка с именем B
. Если вы это сделаете, Git переключится на него. Но если нет, непосредственно перед тем, как сказать «Я не могу переключиться на это, потому что этого не существует», команда checkout или switch (в зависимости от того, какую вы использовали) увидит, есть ли какие-то очевидные origin/B
, которые можно использовать для создания B
. Если это так, команда Git создаст B
с помощью origin/B
,3, а затем переключится на него. На самом деле так работает шаг 6 из git clone
.
4Технически эти имена для удаленного отслеживания находятся в отдельном пространстве имен. Полное написание имени удаленного отслеживания начинается с refs/remotes/
, а полное написание имени ветки начинается с refs/heads/
. Git обычно удаляет части refs/remotes/
и refs/heads/
. Как ни странно, под git branch -a
имена удаленного отслеживания перечислены без refs/
.
2Это предполагает, что указанное переключение возможно. Это возможно, если вы находитесь в «чистом» состоянии, т.е. ничего не меняли. Иногда это возможно, даже если нет. См. также Извлечь другую ветку, если в текущей ветке есть незафиксированные изменения
3На самом деле здесь работает любое имя удаленного отслеживания, даже если оно начинается не с origin/
. Часть «использование» означает, что ваша новая ветка создается с использованием того же идентификатора хэша коммита, который хранится в имени удаленного отслеживания вашего собственного репозитория.