Git змінити гілку, коли присутній файл з однойменною назвою


83

У моєму репозиторії git є файл xyz. За збігом обставин у мене також є філія xyz. На даний момент я працюю на майстрі, але я хочу оформити замовлення до гілки xyz. Команда, яку слід використовувати, проста

$ git checkout xyz

Але це дозволить перевірити файл xyzна поточну HEAD. Як змінити свою гілку на гілку xyz?

Відповіді:


124

Як проілюстровано комітом a047faf (git 1.8.4.3+), ви також можете спробувати:

git checkout xyz --

(Примітка: повідомлення про помилку буде зрозумілішим із Git 2.21, Q1 2019 )

Це дало б зрозуміти, що xyzчастина є гілкою або комітом, тоді як все після --повинно бути шляхом (тут жоден шлях не вказаний). Детальніше тут про конвенцію про подвійні дефіси .

Якщо ви спробуєте без ' --', це може працювати, а може не працювати, як показано в " Чому git checkout <remote_branchname>не створює нову гілку відстеження? ":

git checkout name робить:

  • якщо це локальна гілка або явна віддалена гілка, перейдіть до неї.
  • якщо це відстежений шлях, скиньте його
  • якщо це віддалена гілка, створіть гілку відстеження та перейдіть до неї.

І його поведінка не завжди однакова. Звідси - ' --', щоб дати чітке неоднозначність.


Оновлення серпня 2019 р., Git 2.23+

git checkoutзанадто заплутаний і замінений на:

  • git switch: значення git switch xyzпрацює, навіть якщо у вас є файл xyz,
  • git restore: значення git restore xyzбуде працювати, навіть якщо у вас є філія xyz.

Плюс, як я пояснював у " Чому мій репозиторій Git увійшов у від'єднаний стан HEAD? ", Більше несподіваних відокремлених HEAD.


1
Краще рішення, IMO: stackoverflow.com/a/9537923/1096596
BobbyA

@BobbyA Я оновив відповідь ще кращою відповіддю
VonC

5

Поки рішення VonC працює, я ніколи не пам’ятаю синтаксис, тому зазвичай використовую більш низькотехнологічне рішення:

$ (cd somedir && git checkout my-branch)

Або якщо у вас немає підкаталогів:

$ (cd .git && git -C .. checkout my-branch)

Це легше запам'ятати, і це працює ;-)


0

Git 2.21 (Q1 2019, 4+ роки пізніше) пояснить повідомлення про помилку та внесе пропозиції

" git checkout frotz" ( без жодної подвійної риски, яку я пропонував спочатку ), уникає двозначності, переконуючись, що ' frotz' не може бути інтерпретовано як перегляд і як шлях одночасно .

Ця безпека була оновлена, щоб також перевірити унікальну гілку віддаленого відстеження ` frotz` у пульті дистанційного керування, коли dwimming створює локальну гілку ' frotz' з гілки віддаленого відстеження ' frotz' з пульта.

Примітка: "dwim" (використовується нижче) означає "робити те, що я маю на увазі" , коли комп'ютерна система намагається передбачити те, що мають намір зробити користувачі, виправляючи тривіальні помилки автоматично, а не сліпо виконуючи явні, але потенційно неправильні дані користувача.

Див. Коміт be4908f (13 листопада 2018 р.) Нгуєна pcloudsТхая Нгюка Дуя ( ) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 8d7f9db , 04 січня 2019)

checkout: усунути неоднозначність гілок відстеження dwim та локальних файлів

Коли dwim checkout додається у коміті 70c9ac2 , він обмежується лише dwim, коли виконуються певні умови, інакше повертається до поведінки перевірки за замовчуванням.

Виявляється, падіння назад може заплутати.

Одна з умов повернути

git checkout frotz

до

git checkout -b frotz origin/frotz

це те, що frotzне повинно існувати як файл.

Але коли користувач очікує " git checkout frotz" створення гілки " frotz" і там трапляється файл із назвою " frotz", git тихо повертає frotzвміст файлу " " не допомагає .
Про це повідомляється в списку розсилки Git і навіть використовується як приклад "Git - це погано" в інших місцях .

Зазвичай ми намагаємось робити правильно, але коли є кілька "правильних речей", найкраще залишити це за рішенням користувача.

Перевірте цей випадок, попросіть користувача не визначити:

  • " git checkout -- foo" перевірить шлях "foo"
  • " git checkout foo --" буде dwim і створить гілку " foo" 6

Для користувачів, які не хочуть dwim, використовуйте --no-guess. У цьому конкретному випадку це марно, оскільки " git checkout --no-guess foo --" просто не вдасться.
Але його могли використовувати сценарії.

Наразі сторінкаgit checkout керівництва включає:

--no-guess:

Не намагайтеся створити гілку, якщо існує віддалена гілка відстеження з однойменною назвою.


До Git 2.26 (І квартал 2020 р.) " git checkout X" Неправильно зазнав помилки, коли Xне є локальною гілкою, але міг назвати кілька гілок віддаленого відстеження (тобто бути розміщеною як початкову точку для створення відповідної локальної гілки), яка була виправлений.

Див. Коміт fa74180 , коміт 2957709 (30 грудня 2019 р.) Олександром Мілославським ( SyntevoAlex) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті d0e70cd , 05 лютого 2020)

checkout: не повертати файл на неоднозначних гілках відстеження

Підписав: Олександр Мілославський

Для кращого розуміння, ось такі хороші сценарії:

  1. Не мають файлу ` foo`, немає локальної гілки ' foo' та жодної віддаленої гілки ' foo'
  2. git checkout fooстворить локальну гілку foo, див. коміт 70c9ac2 вище , обговорений тут .

і

  1. Є в файл « foo», немає місцевого відділення « foo» і одного віддаленого філії « foo»
  2. git checkout fooбуде скаржитися, див. коміт be4908f вище

Цей патч запобігає наступному сценарію:

  1. Є в файл « foo», немає місцевого відділення « foo» і кілька віддалених філій « foo»
  2. git checkout fooбуде успішно ... повернути вміст файлу foo!

Тобто додавання іншого пульта дистанційного керування раптово істотно змінює поведінку, що в кращому випадку є несподіванкою, а в гіршому може залишитися непоміченим для користувача.
Будь ласка, зверніться до комітету be4908f вище , який містить деякі скарги у реальному світі.

Наскільки я розумію, виправлення у коміті be4908f вище ( обговорювалося тут ) не враховувало випадок декількох пультів дистанційного керування, і вся поведінка повернення до файлу, що повертає, ніколи не передбачалася:

  • коміт 70c9ac2 вище вводить несподівану поведінку.
    Раніше був запасний варіант з not-a-ref на pathspec. Це розумний резервний варіант.
    Згодом є ще один відкат від неоднозначно-віддаленого до pathspec.
    Я розумію, що це було недоглядання копіювання та вставлення.

  • зафіксуйте ad8d510 з " Неможливо зробити замовлення з кількома пультами " і обговорювали тут , помітив несподівану поведінку, але вирішив напівдокументувати її, а не забороняти, оскільки мета серії виправлень була зосереджена на чомусь іншому.

  • коміт be4908f вище додає, die()коли між гілкою та файлом є неоднозначність.
    Випадки декількох гілок відстеження, мабуть, не враховуються.

Нова поведінка: якщо немає локальної гілки та декількох віддалених кандидатів, просто die()не намагайтеся повернути файл, чи існує він (запобігає сюрпризу) чи ні (покращує повідомлення про помилку) .


З Git 2.30 (Q1 2021) " git checkout" ( людина ) навчився використовувати checkout.guessзмінну конфігурації та відповідно ввімкнути / вимкнути її --[no-]guessопцію.

Див. Коміт 64f1f58 (07 жовтня 2020 р.) Та коміт ef09e7d (06 жовтня 2020 р.) Дентона Лю ( Denton-L) .
(Об’єднано Junio ​​C Hamano - gitster- у комітеті 0e41cfa , 27 жовтня 2020)

checkout: навчись поважати checkout.guess

Підписав: Дентон Лю

Поточна поведінка git checkout/switch, яка --guessв даний час увімкнена за замовчуванням.
Однак деякі користувачі можуть не бажати, щоб це відбувалося автоматично.
Замість того, щоб змушувати користувачів --no-guessкожного разу вказувати вручну, навчіть ці команди checkout.guessзмінної конфігурації, яка дає користувачам можливість встановити поведінку за замовчуванням.

Навчіть сценарій завершення розпізнавати нову змінну конфігурації та вимкнути логіку DWIM, якщо для неї встановлено значення false.

git configтепер включає в свою довідкову сторінку :

checkout.guess

Надає значення за замовчуванням для параметра --guessабо --no-guess в git checkoutі git switch. Дивіться git switchі git checkout.

git checkoutтепер включає в свою довідкову сторінку :

--guessє поведінкою за замовчуванням. Використовуйте --no-guessдля його вимкнення.

Поведінку за замовчуванням можна встановити за допомогою checkout.guessзмінної конфігурації.

git switchтепер включає в свою довідкову сторінку :

Поведінку за замовчуванням можна встановити за допомогою checkout.guessзмінної конфігурації.


-3

Ви помиляєтеся. Він перевірить відділення xyz.

Щоб оформити файл, потрібно скористатися командою git checkout -- xyz. Git просто дозволяє вам ярлик для файлів, якщо немає гілки з однаковим ім'ям.

Детальніше git checkout --helpдив.


9
Чому я ставлю питання, якщо цього не відбувається? Я зі мною відбуваюся. Як правило, на перевірку відділення, відповідь є Switched to branch 'xyz', але в моєму випадку відповіді не було. Що є звичайним сценарієм перевірки файлу. Крім того, я бачив результати, git branch -vaщоб зробити висновок, що таких змін не відбулося.
venky
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.