Перемістіть покажчик відділення на різні комісії без оформлення замовлення


759

Для переміщення вказівника гілки перевіреної гілки можна скористатися git reset --hardкомандою. Але як перемістити покажчик гілки не перевіреної гілки, щоб вказати на інший фіксатор (зберігаючи всі інші речі, такі як відстежена віддалена гілка)?


11
Звучить, що все, що ви хотіли зробити, - це гілка з іншого комітету, ніж те, яке воно створюється зараз. Якщо моє розуміння правильне, то чому б ви просто не створити нову гілку з комітету, який ви хочете створити, використовуючи git branch <branch-name> <SHA-1-of-the-commit>та скидаючи стару гілку?
yasouser

6
@yasouser - Я не впевнений, що хороша ідея, демпінг "майстер" гілки
Bulwersator

Відповіді:


578

Ви можете це зробити для довільних відмов. Ось як перемістити вказівник гілки:

git update-ref -m "reset: Reset <branch> to <new commit>" refs/heads/<branch> <commit>

Загальна форма:

git update-ref -m "reset: Reset <branch> to <new commit>" <ref> <commit>

Якщо вам подобається, ви можете вибрати гниди щодо повідомлення про відкладення - я вважаю, що це branch -fодне інакше, ніж це reset --hard, і це точно не одне з них.


39
Де добре це повідомлення? Де він зберігається і як його читати пізніше?
Пн

4
ПРИМІТКА. Це не працює у голих сховищах. У голих сховищах вам потрібно використовувати 'git гілка -f master <commit>' для оновлення гілки (див. Відповідь нижче).
Червень Родос

37
Якщо, як і я, ви випадково використовуєте <branch> замість refs / heads / <branch>, ви отримаєте новий файл у вашому .git каталозі за адресою .git / <branch>, і ви отримаєте повідомлення типу "перейменувати" майстер "неоднозначно", коли ви намагаєтесь працювати з ним. Ви можете видалити файл із каталогу .git, щоб виправити.
Девід Мінор

34
Задоволено не було пояснено, чому це краще, ніж git branch -f. Якщо конкретніше, цей метод видається таким: (А) складніше у використанні (В) складніше запам’ятовувати, та (С) більш небезпечним
Стівен Лу

10
"що саме мається на увазі під умовними відповідьми" - Відділення не є єдиним видом посилання, що вказує на зобов'язання. Є теги, і ви також можете створювати довільні refs / whatevs / myref стилі refs самостійно, які не є ні гілками, ні тегами. Я вважаю, що це також відповідає на питання Стівена Лу про те, що це може бути "кращим". Я погоджуюсь, галузь -f найпростіше, якщо ви працюєте з гілками.
Адам А

962
git branch -f <branch-name> <new-tip-commit>

24
Або для довільних рефов, git update-ref -m "reset: Reset <branch> to <new commit>" <branch> <commit>. (Ви можете вибрати гниди про повідомлення про відмову, якщо вам подобається - я вважаю, що branch -fодне відрізняється від того reset --hard, і це не зовсім жодне з них.)
Cascabel

4
Джефромі, будь ласка, напишіть окрему відповідь, щоб ви могли отримати голоси. :)
Пн

16
Це краща відповідь, оскільки він обробляє 99% випадків і фактично відповідає документації. git help branchкаже "-f, --force Скиньте <branchname> до <startpoint>, якщо <branchname> вже існує. Без -f git гілка відмовляється змінити існуючу гілку."
AlexChaffee

12
Я роблю, git branch -f master <hash>і це говорить мені fatal: Cannot force update the current branch.Ummmm, що я повинен робити, що зараз, перевірити якусь іншу випадкову гілку, перш ніж я можу використовувати цю команду?
Qwertie

20
Це не спрацює, якщо гілка, яку ви намагаєтеся перемістити, - ваша поточна гілка ( HEADвказує на неї).
Володимир Пантелеєв

135

Ви також можете передавати git reset --hardпосилання на комісію.

Наприклад:

git checkout branch-name
git reset --hard new-tip-commit

Я вважаю, що роблю щось подібне напівчасто:

Якщо припустити цю історію

$ git log --decorate --oneline --graph
* 3daed46 (HEAD, master) New thing I shouldn't have committed to master
* a0d9687 This is the commit that I actually want to be master

# Backup my latest commit to a wip branch
$ git branch wip_doing_stuff

# Ditch that commit on this branch
$ git reset --hard HEAD^

# Now my changes are in a new branch
$ git log --decorate --oneline --graph
* 3daed46 (wip_doing_stuff) New thing I shouldn't have committed to master
* a0d9687 (HEAD, master) This is the commit that I actually want to be master

Це має найбільш сенс у тому, що зазвичай використовується HEAD або HEAD ^ для переміщення кінця гілки назад у часі. Таким чином, це послідовно, щоб вказати наперед зобов'язання.
justingordon

11
Це добре, якщо ваше робоче дерево чисте. Якщо у вас багато поетапних або нестандартних змін, це, мабуть, краще зробити, git update-refяк було сказано вище.
платний ботанік

16
Ви помітили, що ваша "відповідь" не додає нічого, що вже не є частиною питання ?? - ОП сказав: якщо це перевірено ... ви можете використовувати git reset --hard ...Не потрібно повторювати це тут! :-(
Роберт Сімер

6
@Robert: Я не згоден. Питання не говорило, як ним користуватися, і це робить. Приємно було не їхати шукати, як це.
Вілсон F

7
@WilsonF, можливо, вам було приємно знайти це тут, але це зовсім не відповідає на питання. Можливо, це відповідь на якесь інше питання, але тут це неправильно .
Роберт Сімер

52

Просто для збагачення дискусії, якщо ви хочете перенести myBranchвідділення на свій поточний комітет, просто опустіть другий аргумент після-f

Приклад:

git branch -f myBranch


Я, як правило, це роблю, коли rebaseперебуваю в стані окремої головки :)


13

В gitk --all:

  • клацніть правою кнопкою миші на потрібній фіксації
  • -> створити нове відділення
  • введіть назву існуючої гілки
  • натисніть клавішу return у діалоговому вікні, що підтверджує заміну старої гілки цього імені .

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

Було б здорово, якби gitkбула функція, де у діалоговому вікні було 3 варіанти: перезаписати, змінити існуючі або скасувати.


Навіть якщо ви, як правило, наркоман з командного рядка, як я, git guiі gitkцілком чудово розроблені для підмножини використання git, яку вони дозволяють. Я настійно рекомендую використовувати їх для того, у чому вони хороші (тобто вибірково влаштовує перехитування до / з індексу в git gui, а також просто вчинення. (Ctrl-s для додавання підписаного: рядок, ctrl-enter для фіксації .)

gitk чудово підходить для відстеження декількох гілок, поки ви розбираєте свої зміни в приємній серії виправлень, що надсилаються вгору, або будь-що інше, де вам потрібно відслідковувати те, що ви знаходитесь в середині, з кількома гілками.

У мене навіть браузер графічного файлу не відкритий, але я люблю gitk / git gui.


1
Так легко! Я, можливо, щойно перейшов з gitg в gitk.
Майкл Коул

Однак таким чином втрачається інформація про галузь відстеження.
mbdevpl

@mbdevpl: Я не дуже фахівець з git. Я думаю, я розумію, що ви маєте на увазі, але не наслідки. Я використовував це досить часто, і досі вдається висувати ці гілки на однойменні гілки на пульті. Що для вас робить асоціація між філією та її відділенням дистанційного відстеження?
Пітер Кордес


1
@PeterCordes Ineed, коли назви гілок не відповідають цьому. Також коли є більш ніж один пульт. Крім того, коли ви використовуєте підказку git для відображення стану філії, вона відображатиме відстань до філії відстеження (якщо вона встановлена). Також git statusвпливає на вихід. Крім того, в деяких випадках git fetchі git pushне працюватиме без вказівки віддаленого явно , якщо ви не встановите гілку відстеження. Я не знаю про всі випадки, але для мене загальним правилом є те, що для зручності та швидкості роботи краще мати відстеження гілок у порядку.
mbdevpl

7

Рекомендоване рішенняgit branch -f branch-pointer-to-move new-pointer в TortoiseGit :

  • "Журнал Git Show"
  • Поставте прапорець "Усі відділення"
  • У рядку, на який потрібно перемістити вказівник гілки (new-pointer):
    • Клацніть правою кнопкою миші "Створити відділення в цій версії"
    • Поруч із "Відділення" введіть назву гілки для переміщення (гілка-вказівник на переміщення)
    • У розділі "Base On" перевірте правильність нового покажчика
    • Поставте прапорець "Сила"
    • Добре

введіть тут опис зображення

введіть тут опис зображення


4

Чесно кажучи, я здивований, як ніхто не думав про git pushкоманду:

git push -f . <destination>:<branch>

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

Хоча ця команда використовується для збереження змін на вашому сервері, результат точно такий же, як якщо переміщення віддаленої гілки ( <branch>) до того ж комітету, що і локальна гілка ( <destination>)


Ви також можете це зробити, не -fуникаючи прищеплення нічого місцевого; Наприклад, git fetch origin && git push . origin/develop:developце не потрібна невдача версіяgit checkout develop && git pull --ff-only
квітня

1

Відкрийте файл .git/refs/heads/<your_branch_name>і змініть збережений там хеш на той, куди ви хочете перемістити голову своєї філії. Просто відредагуйте та збережіть файл у будь-якому текстовому редакторі. Просто переконайтесь, що гілка для зміни не є поточною активною.

Відмова: Мабуть, це не доцільний спосіб зробити це, але робота виконується.


1
Не впевнений, чи це хаотичний чи злий спосіб це зробити. 🤔 😉
Кіт Рассел

@KeithRussell може бути обома: P
Гільєрмо Гутьєррес

0

У випадку, якщо зобов’язання, на яке ви хочете вказати, випереджає поточну гілку (що повинно бути так, якщо ви не хочете скасувати останні коміти поточної гілки), ви можете просто зробити:

git merge <commit>

Питання задавали, що робити, якщо філія не перевірена.
Кіт Рассел

На жаль, я пропустив цю точку. У такому випадку ви можете зробити так, git push . <commit>:<branch>як уже запропоновано.
Жан Пол
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.