Переключити гілку Git без оформлення файлів


100

Чи можливо в Git перейти на іншу гілку без перевірки всіх файлів?

Після перемикання гілки мені потрібно видалити всі файли, відновити їх, здійснити і переключити назад. Тож перевірка файлів - це лише марна трата часу (а файлів близько 14 000 - це довга операція).

Щоб все було зрозуміло:

Мені потрібно все це для завантаження документації в GitHub.

У мене є сховище з відділенням gh-pages . Коли я перероблюю документацію локально, я копіюю її в каталог сховища, виконуючи їх і натискаю на GitHub. Але я не був задоволений, бо мав дві копії документації на місцях. І я вирішив створити порожню гілку і після вчинення переключитися на порожні та видалити файли. Але переключення назад - це довга операція - тому я задав це питання.

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


Як довго у вас "довго"? На якій платформі ви працюєте? Ви працюєте в мережі, наприклад, з NFS або іншим спільним файлом?
Грег Хьюгілл

Яка мета цієї вправи? Ви хочете мати дві гілки, в одній з детальними записами, у другій записуються лише основні зміни (грубозернисті)?
Якуб Нарбський

Можливо, дешевше створити тимчасовий (або постійний?) Клон вашої робочої копії. Мій родинний відповідь і рецензія показати , як це працює навіть як підкаталог основного сховища.
krlmlr

Відповіді:


106

Так, ви можете це зробити.

git symbolic-ref HEAD refs/heads/otherbranch

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

git reset

1
Використання echo "ebff34ffb665de0694872dceabe0edeaf50ec5a9" > .git/HEADслід git resetвказати на реф замість філії.
cadorn

1
Безпосереднє записування у файл HEAD менш надійне. Що робити, якщо ви знаходитесь у піддіректорі? Для відірваної голови (голова, що вказує безпосередньо на SHA1), спробуйте: git update-ref HEAD refs/heads/otherbranch
Олександр Птах

2
Якщо ви хочете перевірити свіжу гілку з поточної гілки, ще один спосіб зробити це - 1. git stash2. git checkout -b otherBranch3.git stash pop
Вінні

@AlexanderBird: git update-refкорисно, але воно також переміщує кінчик поточної гілки.
tomekwi

47

Використовуючи лише основні команди git:

Ця відповідь трохи довша, ніж у Чарльза, але вона складається виключно з основних команд git, які я можу зрозуміти і таким чином запам’ятати, усуваючи необхідність продовжувати її шукати.

Позначте своє поточне місцеположення (за потреби скористайтеся першим):

git checkout -b temp

Скиньте (перемістить) маркер на іншу гілку, не змінюючи робочий dir:

git reset <branch where you want to go>

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

git checkout <branch where you want to go>

так як ваша ГОЛОВА вже вказує на той самий вчинок, робочий режисер не торкається

git branch -d temp

Зауважте, що ці команди також доступні для будь-якого графічного клієнта.


7
Я вважаю за краще git reset --soft <branch where you want to go>уникати оновлення індексу
JoelFan

7
Я погоджуюся з вашою стратегією уникнення команд git сантехніка та віддати перевагу порцеляновим.
користувач64141

26

У v2.24 git switch- це щось на кшталт безпечного git checkout.
Тому я перейменував псевдонім нижче git hopдля
«стрибка на гілці , не змінюючи worktree»

Для користі читача:

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

git checkout --detach
git reset --soft commitish
git checkout commitish

Пояснили:

  • git checkout --detachте саме, git checkout HEAD^{}що залишає поточну гілку позаду і переходить у "відокремлений головний стан". Тож наступна модифікація HEADбільше не стосується жодної галузі. Процедура відключення HEADне впливає на worktree , ні індекс.
  • git reset --soft commitishпотім переходить HEADдо SHA даного commitish. Якщо ви хочете оновити індекс, також залишайте --softподалі, але я не рекомендую цього робити. Це, знову ж таки, не торкається робочого дерева та ( --soft) не індексу.
  • git checkout commitishпотім знову приєднується HEADдо даної commitish(гілки). (Якщо commitishце SHA, нічого не відбувається.) Це також не впливає на індекс і робоче дерево.

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

Це призводить до наступного git hop treeishпсевдоніму:

git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'

FYI, ви можете знайти його в моєму списку gitпсевдонімів .


Ви не хочете використовувати, $@а не $*? Різниця полягає в тому, що $ @ з нерозширеними цитованими аргументами, у яких всередині є пробіли.
киб

1
@kyb Функція хитрості вкрадена з іншої відповіді ТА . І $@тут остаточно не мається на увазі. $*використовується замість того $1, що git switch -f bстає тим самим, git switch '-f b'що має бути помилкою. Таким чином я можу скоротити псевдонім, відмовившись від обробки помилок на зразок!f() { [ 1 = $# ] || { echo 'WTF!'; return 1; }; ..
Tino

Дуже хороше рішення. Тим більше, що його можна використовувати для віддалених гілок!
Nils-o-mat

14

Не було б кращим рішенням мати два робочих каталоги (дві робочі області) з одним сховищем або навіть двома сховищами?

У розділі є інструмент git-new-workdir, який contrib/допоможе вам у цьому.


Чи git-new-workdir збігається з власною командою worktree? Я використовую робоче дерево, коли хочу перевірити гілку в іншу папку (без клонування всього репо).
Рюу

У git-new-worktreeпопередньої сценарій git worktreeпідкоманду; ця команда була недоступною, коли відповідь була написана. Наприклад, для сценарію потрібна підтримка symlink; ІМХО, краще використовувати вбудовану підтримку.
Якуб Нарбський

8

Я думаю, ти шукаєш сантехнічну команду git read-tree. Це оновить індекс, але не оновить жодних файлів у вашому робочому каталозі. Наприклад, припустимо branch, що назва гілки читати:

git read-гілка дерева

Якщо ви хочете взяти на себе зобов’язання з галуззю, яку ви тільки що прочитали, вам також потрібно буде:

git символічно-ref HEAD refs / голови / відділення

ні, мені потрібно лише переключити відділення, ніяких інших змін - так символічний перегляд досить хороший
тиг

read-treeстворює помилку: fatal: Not a valid object name branchякщо її ще не git switch branchбуло
Андрій

7

Ви можете перезаписати файл HEAD з іншою назвою гілки:

echo "ref: refs / heads / MyOtherBranch"> .git / HEAD


13
Мабуть, краще скористатися командою символічного ref, щоб зробити це для вас: git symbolic-ref HEAD refs/heads/MyOtherBranch kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html
Грег Хьюгілл

@GregHewgill, це єдиний спосіб, який мені відомо про переміщення HEAD до хеш-файлів. Ви можете це зробити git symbolic-ref?
tomekwi

0

З такою кількістю файлів, можливо, вам найкраще зберегти два репости, по одному для кожної гілки. За потреби можна перетягувати зміни вперед і назад. Це стане менш дивовижним, ніж спроба зіграти витівки цинги з git.


Ви можете використовувати git-new-worktreeдля цього замість (у contrib/)
Якуб Нарбський

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

0

Якщо ви просто намагаєтесь змінити, де знаходиться віддалена гілка, ви можете це зробити "git push", не торкаючись локальної копії.

http://kernel.org/pub/software/scm/git/docs/git-push.html

Формат параметра <refspec> - необов'язковий плюс +, за ним - джерело ref <src>, а потім двокрапка: і далі ref <dst>. Він використовується для вказівки, з яким об'єктом <src> об'єкт повинен оновити <dst> ref у віддаленому сховищі.

наприклад, для оновлення foo для здійснення c5f7eba виконайте наступне:

git push origin c5f7eba:foo

Не впевнений, це ти був, чи ні.


На питання вже отримано відповідь: stackoverflow.com/questions/1282639/…
tig

0

ви можете скористатися

      1. git checkout -f <new-branch>
      2. git cherry-pick -x <previous-branch-commit-id>

previous-branch-commit-id - це команда, з якої потрібно скопіювати старі дані.


0

Або просто скористайтеся файлом патча, щоб виправити з іншого відділення свого майстра

git diff otherbranch master > ~/tmp/otherbranch.diff
git checkout master
git apply ~/tmp/otherbranch.diff

-1

скажіть, ви хочете бути у відділенні A, але з файлами з гілки B

знайдіть поточний номер філії A з журналом git, наприклад, "99ce9a2",

git checkout A
git reset --hard B
git reset 99ce9a2

тепер ви повинні знаходитись на гілці A зі структурою папок, що відповідає B, які відображаються як нестандартні зміни (Історія не змінилася).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.