Як змінити вказаний коміт?


2233

Зазвичай я надсилаю на перегляд список комітетів. Якщо у мене є такі зобов'язання:

  1. HEAD
  2. Commit3
  3. Commit2
  4. Commit1

... Я знаю, що можу змінити фіксацію голови git commit --amend. Але як я можу змінити Commit1, враховуючи, що це не HEADзобов'язання?


31
Дивіться альтернативну відповідь тут: stackoverflow.com/a/18150592/520567 Ваша прийнята відповідь - це дійсно точна відповідь на ваше запитання, але якщо ви готові до нових зобов’язань, перш ніж ви вирішили скористатися редагуванням, то ця відповідь буде більш зрозумілою. Він також може працювати з декількома комісіями, які ви хочете об'єднати / згорнути разом зі старшим.
акостадінов

6
Крім того, ви можете просто побачити розділення комісії в Git Tools - Переписування історії для отримання додаткової інформації.
хакре

Можливий дублікат способу змінити існуючі, незапущені коміти?
tkruse

Відповіді:


2955

Ви можете використовувати git rebase . Наприклад, якщо ви хочете змінити фіксацію bbc643cd, запустіть

$ git rebase --interactive 'bbc643cd^'

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

У редакторі за замовчуванням змініть pickна editрядок, в якому згадується 'bbc643cd'.

Збережіть файл та вийдіть: git буде інтерпретувати та автоматично виконувати команди у файлі. Ви опинитеся в попередній ситуації, в якій ви щойно створили зобов'язання bbc643cd.

На даний момент bbc643cdце ваше останнє зобов’язання, і ви можете легко змінити його : внесіть зміни, а потім виконайте їх командою:

$ git commit --all --amend --no-edit

Після цього введіть:

$ git rebase --continue

щоб повернутися до попередньої комісії HEAD.

Попередження : Зауважте, що це змінить SHA-1 цього комітету, як і всі діти - іншими словами, це переписує історію з цього моменту вперед. Ви можете порушити репост, роблячи це, якщо натиснути за допомогою командиgit push --force


125
Ще один цікавий варіант цього потоку - це коли ви перейшли до комісії, яку хочете змінити, замість того, щоб змінювати файли та розміщуватись над командою зверху (ту, яку ви редагуєте), ви можете розділити цю команду на дві різні коміти (або навіть більше). У цьому випадку поверніться до редакції для редагування та запустіть "git reset HEAD ^". що поставить модифіковані файли цього комітету на стадію. Тепер виберіть і введіть будь-які файли за своїм бажанням. Цей потік досить добре пояснений на сторінці "git-rebase". Див. Розділ "Розбиття комітів". bit.ly/d50w1M
Дієго Піно

200
У Git 1.6.6 та новіших версіях ви можете використовувати rewordдію git rebase -iзамість edit(вона автоматично відкриває редактор та продовжує виконувати інші кроки ребазування; це скасовує використання git commit --ammendта git rebase --continueколи вам потрібно лише змінити повідомлення про фіксацію, а не вміст ).
Кріс Джонсен

108
Варто зазначити, що вам можуть знадобитися запустити git stashдо git rebaseі git stash popпісля, якщо у вас є зміни, що очікують на розгляд.
користувач123444555621

3
Чи існує команда швидкого доступу для редагування конкретного комітету в інтерактивній базі даних, не відкриваючи редактор, не знаходячи фіксацію, позначаючи її редагуванням, а потім повертаючись до командного рядка?
sstur

15
Зауважте, що з новішими git було б розумніше дотримуватися інструкцій підказки, а не сліпо використовувати git commit --all --amend --no-editтут. Все, що я мав робити після git rebase -i ...- це git commit --amendнормально тоді git rebase --continue.
Ерік Чен

452

Використовуйте дивовижну інтерактивну базу даних:

git rebase -i @~9   # Show the last 9 commits in a text editor

Знайдіть потрібну фіксацію, змініть pickна e( edit) і збережіть і закрийте файл. Git повернеться до цього коміту, що дозволяє вам:

  • використовувати git commit --amendдля внесення змін, або
  • використовуйте git reset @~для відмови від останньої фіксації, але не змін у файлах (тобто переведіть вас до того, як ви були, коли ви редагували файли, але ще не здійснили).

Останнє корисно для виконання складніших завдань, таких як розділення на кілька комітетів.

Потім бігайте git rebase --continue , і Git відтворить наступні зміни поверх вашої зміненої комісії. Вас можуть попросити виправити деякі конфлікти злиття.

Примітка: @це скорочення дляHEAD , і ~є фіксацією до зазначеного комітету.

Детальніше про переписування історії читайте в документах Git.


Не бійтеся переобладнати

ProTip ™: не бійтеся експериментувати з "небезпечними" командами, які переписують історію * - Git не видаляє ваші зобов'язання протягом 90 днів за замовчуванням; ви можете знайти їх у рефлозі:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Слідкуйте за такими варіантами, як --hardі --forceхоча - вони можуть відкинути дані.
* Також не переписуйте історію на жодних гілках, над якими ви співпрацюєте.



У багатьох системах git rebase -iVim відкриє за замовчуванням Vim. Vim не працює, як у більшості сучасних текстових редакторів, тому погляньте, як перезавантажити за допомогою Vim . Якщо ви хочете скористатися іншим редактором, замініть його git config --global core.editor your-favorite-text-editor.


29
Середина вашої відповіді - це дивне місце, щоб розмістити те, що я можу описати лише як рекламу мінімізації для VIM. Це питання не має значення і просто захаращує вашу відповідь.
Намір

21
@Intentss: Ах, я бачу, чому це виглядало дивно. Підставою для цього стало те, що Vim є текстовим редактором за замовчуванням у багатьох системах, тому перший досвід інтерактивного перезапису у багатьох людей - це екран, на якому введення змушує курсор летіти по всьому світу. Потім вони перемикають свого редактора на щось інше, і їх другий досвід інтерактивного перезапису є цілком нормальним, але залишає їх цікавити, чому він використовує текстовий файл замість GUI. Щоб досягти потоку за допомогою перезавантаження, вам потрібно щось на кшталт Vim або Emacs-режиму Rebase.
Заз

9
Добре. Бачачи, як так багато людей вважають цю частину неактуальною, я скоротив її до 3 рядків, а також пояснив, як потрібно змінити редактор, якщо потрібно.
Заз

17
Дивовижно! Я не знав, що ти можеш використовувати @як стенограму HEAD. Дякуємо, що опублікували це.
Джеймс Ко

3
git reset @~саме те, що я хотів зробити, вибравши прихильність git rebase .... Ти мій герой)
18augst

79

Інтерактивна база даних з--autosquash то , що я часто використовую , коли мені потрібно FixUp попередніх коммітов глибше в історії. Це суттєво прискорює процес, який ілюструє відповідь ZelluX, і особливо зручний, коли у вас є більше одного зобов’язання, яке потрібно редагувати.

З документації:

--autosquash

Коли повідомлення журналу фіксації починається з "сквош! ..." (або "виправлення! ..."), і є коміт, чий заголовок починається з того ж…, автоматично змінюйте список todo ребаза -i так, що фіксація Позначені для скрешчування надходять відразу після зміни коміту

Припустимо, у вас є історія, яка виглядає приблизно так:

$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1

і у вас є зміни, які ви хочете внести до змін у Comm2, після чого скористайтеся своїми змінами, використовуючи

$ git commit -m "fixup! Commit2"

альтернативно, ви можете використовувати команду-замість цього повідомлення, а не повідомлення "fixup! e8adec4 або навіть просто префікс повідомлення про фіксацію.

Потім ініціюйте інтерактивну базу даних раніше

$ git rebase e8adec4^ -i --autosquash

ваш редактор відкриється з уже упорядкованими комісіями

pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3

все, що вам потрібно зробити, це зберегти та вийти


21
Ви також можете використовувати git commit --fixup=@~замість git commit -m "fixup! Commit2". Це особливо корисно, коли ваші повідомлення про вчинення довші, і було б болісно набрати всю справу.
Заз

42

Виконати:

$ git rebase --interactive commit_hash^

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

Використовуючи Vim, ви змінюєте слова pickна rewordна документи, які ви хочете змінити, збережіть і вийдіть ( :wq). Тоді git підкаже вам кожне зобов’язання, яке ви позначили як слово, щоб ви могли змінити повідомлення про фіксацію.

Кожне повідомлення про фіксацію, яке вам потрібно зберегти та закрити ( :wq), щоб перейти до наступного повідомлення про фіксацію

Якщо ви хочете вийти без застосування змін, натисніть :q!

EDIT : для навігації vimви використовуєте jдля підйому вгору, kвниз, hвліво та lвправо (все це в NORMALрежимі, натисніть, ESCщоб перейти в NORMALрежим). Щоб відредагувати текст, натисніть iтак, щоб увійти в INSERTрежим, де ви вставляєте текст. Натисніть, ESCщоб повернутися в NORMALрежим :)

ОНОВЛЕННЯ : Ось чудове посилання з переліку github Як скасувати (майже) що-небудь із git


4
Для мене прекрасно працювали. Варто згадати git push --force?
u01jmg3

Що git push --forceозначає перезапис віддалених комісій з вашими місцевими комісіями. Це не так у цій темі :)
betoharres

@BetuUuUu, звичайно, якщо ваші зобов’язання будуть висунуті на віддалений і ви змінили повідомлення про фіксацію локально, ви б хотіли змусити натиснути на віддалений, чи не так?
Судіп Бхандарі

@SudipBhandari Це я відчуваю. Я не змушував, і тепер у мене є додаткова гілка, яка відображає всі зобов'язання назад тому, чиє повідомлення я змінив, що є супер некрасивим.
ruffin

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

18

Якщо вам не подобаються інтерактивні редактори, ви можете використовувати git rebase --onto.

Скажіть, що ви хочете змінити Commit1. По-перше, відгалуження від раніше Commit1 :

git checkout -b amending [commit before Commit1]

По- друге, захоплення Commit1з cherry-pick:

git cherry-pick Commit1

Тепер внесіть зміни, створивши Commit1':

git add ...
git commit --amend -m "new message for Commit1"

І, нарешті, після того, як відклали будь-які інші зміни, пересадіть решту ваших зобов’язань, що перевищує masterнове зобов'язання:

git rebase --onto amending Commit1 master

Читайте: "перезагрузка на гілку amending, всі коміти між Commit1(не включно) та master(включно)". Тобто, Comm2 і Commit3, повністю вирізавши старий Activ1. Ви можете просто забрати їх у вишні, але цей спосіб простіше.

Не забудьте почистити свої гілки!

git branch -d amending

4
ви можете скористатися, git checkout -b amending Commit1~1щоб отримати попередню комісію
Арін Тейлор

Чи рівні перші два кроки git checkout -b amending Commit1?
Хаошу,

16

На підставі документації

Змінення повідомлення старіших або декількох повідомлень про фіксацію

git rebase -i HEAD~3 

Вище наведено список останніх 3 комісій у поточній гілці, змінити 3 на щось інше, якщо ви хочете більше. Список буде схожий на такий:

pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Заміни забрати з перефразувати перед кожним коммітов , який ви хочете змінити. Скажімо, ви змінюєте друге введення у списку, ваш файл буде виглядати наступним чином:

pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

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

Нарешті примусово натисніть на поправки.

git push --force

Я отримую таку помилку: помилка: виникла проблема з редактором 'vi'. Будь ласка, надайте повідомлення за допомогою параметра -m або -F.
Ерік Мейнард

12

Повністю неінтерактивна команда (1)

Я просто думав, що поділюсь псевдонімом, який я використовую для цього. Він заснований на неінтерактивному інтерактивному базі даних . Щоб додати його до свого git, запустіть цю команду (пояснення наведено нижче):

git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"; }; f'

Найбільшою перевагою цієї команди є той факт, що це no-vim .


(1) враховуючи, що конфліктів під час перезавантаження немає, звичайно

Використання

git amend-to <REV> # e.g.
git amend-to HEAD~1
git amend-to aaaa1111

Ім’я amend-toвидається відповідним IMHO. Порівняйте потік із --amend:

git add . && git commit --amend --no-edit
# vs
git add . && git amend-to <REV>

Пояснення

  • git config --global alias.<NAME> '!<COMMAND>'- створює глобальний псевдонім git, <NAME>який буде виконувати команду non-git<COMMAND>
  • f() { <BODY> }; f - функція "анонімного" башу.
  • SHA=`git rev-parse "$1"`; - перетворює аргумент в редагування git і присвоює результат змінній SHA
  • git commit --fixup "$SHA"- виправлення-фіксація для SHA. Див. git-commitДокументи
  • GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"
    • git rebase --interactive "$SHA^" частина була охоплена іншими відповідями.
    • --autosquashце те, що використовується разом з цим git commit --fixup, див. git-rebaseдокументи для отримання додаткової інформації
    • GIT_SEQUENCE_EDITOR=trueце те, що робить всю справу неінтерактивною. Цей хак я дізнався з цієї публікації в блозі .

1
Можна також amend-toобробити файли, що не використовуються, git config --global alias.amend-to '!f() { SHA=git rev-parse "$ 1"; git stash -k && git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^" && git stash pop; }; f'
Dethariel

2
Одна з проблем, пов'язаних з цим методом, полягає в тому, що він може застосовувати непов'язані налаштування.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

Чи не суть питання в тому, щоб змінити повідомлення про фіксацію? Тому що ця відповідь не стосується цього, або, принаймні, безпосередньо.
wytten

@wytten питання не запитує про зміну повідомлення про фіксацію, а про зміну фіксації. Тож відповідь на ваше запитання буде "ні, це не сенс питання"
Детхаріель

Я розгублений, тож як ми можемо змінити повідомлення про фіксацію?
ggb667

8

Автоматизоване інтерактивне редагування бази даних з подальшим відновленням фіксації, готове до завершення

Мені здалося, що виправляю минулу комісію досить часто, що я написав сценарій для цього.

Ось робочий процес:

  1. git commit-edit <commit-hash>
    

    Це відкине вас на комісію, яку ви хочете відредагувати.

  2. Виправте та покладіть комісію так, як хочете, щоб це було в першу чергу.

    (Можливо, ви хочете використовувати git stash saveдля збереження будь-яких файлів, які ви не створюєте)

  3. Повторіть команду --amend, наприклад:

    git commit --amend
    
  4. Заповніть базу даних:

    git rebase --continue
    

Щоб вищезгадане спрацювало, покладіть нижченаведений скрипт у виконуваний файл, який називається git-commit-editдесь у вашому $PATH:

#!/bin/bash

set -euo pipefail

script_name=${0##*/}

warn () { printf '%s: %s\n' "$script_name" "$*" >&2; }
die () { warn "$@"; exit 1; }

[[ $# -ge 2 ]] && die "Expected single commit to edit. Defaults to HEAD~"

# Default to editing the parent of the most recent commit
# The most recent commit can be edited with `git commit --amend`
commit=$(git rev-parse --short "${1:-HEAD~}")
message=$(git log -1 --format='%h %s' "$commit")

if [[ $OSTYPE =~ ^darwin ]]; then
  sed_inplace=(sed -Ei "")
else
  sed_inplace=(sed -Ei)
fi

export GIT_SEQUENCE_EDITOR="${sed_inplace[*]} "' "s/^pick ('"$commit"' .*)/edit \\1/"'
git rebase --quiet --interactive --autostash --autosquash "$commit"~
git reset --quiet @~ "$(git rev-parse --show-toplevel)"  # Reset the cache of the toplevel directory to the previous commit
git commit --quiet --amend --no-edit --allow-empty  #  Commit an empty commit so that that cache diffs are un-reversed

echo
echo "Editing commit: $message" >&2
echo

7

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

Примітка. Я представляю такий підхід заради ілюстрації того, що ви можете зробити, а не щоденної альтернативи. Оскільки він має багато кроків (і, можливо, деякі застереження.)

Скажіть, що ви хочете змінити фіксацію, 0і ви зараз увімкненоfeature-branch

some-commit---0---1---2---(feature-branch)HEAD

Отримайте замовлення на цю комісію та створіть quick-branch. Ви також можете клонувати свою гілку функції як точку відновлення (перед запуском).

?(git checkout -b feature-branch-backup)
git checkout 0
git checkout -b quick-branch

Тепер у вас буде щось подібне:

0(quick-branch)HEAD---1---2---(feature-branch)

Зміни сцени, приховуйте все інше.

git add ./example.txt
git stash

Внесіть зміни та поверніться до feature-branch

git commit --amend
git checkout feature-branch

Тепер у вас буде щось подібне:

some-commit---0---1---2---(feature-branch)HEAD
           \
             ---0'(quick-branch)

Rebase feature-branchна quick-branch(дозволити будь-які конфлікти шляхом). Нанесіть приховування та видаліть quick-branch.

git rebase quick-branch
git stash pop
git branch -D quick-branch

І закінчуєте ви:

some-commit---0'---1'---2'---HEAD(feature-branch)

Git не буде дублюватись (хоча я не можу реально сказати в якій мірі) 0 виконувати при перезапуску.

Примітка: всі хеші фіксації змінюються, починаючи з фіксації, яку ми спочатку мали намір змінити.


6

Щоб отримати неінтерактивну команду, покладіть сценарій із цим вмістом у свою PATH:

#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"

Використовуйте його, інсценізуючи зміни (з git add), а потім запустіть git fixup <commit-to-modify>. Звичайно, він все одно буде інтерактивним, якщо у вас виникнуть конфлікти.


1
Це добре працює. Я додав додаткову функціональність для того, щоб виконувати виправлення поодиноких брудних дерев для вдосконалення набору комітів. `dirtydiff = $ (git diff); if ["$ {dirtydiff}"! = ""]; потім відлуння "Затоплення брудного дерева"> & 2; git stash; fi;
Саймон Фельтман

6

git stash+ rebaseавтоматизація

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

git-amend-old() (
  # Stash, apply to past commit, and rebase the current branch on to of the result.
  current_branch="$(git rev-parse --abbrev-ref HEAD)"
  apply_to="$1"
  git stash
  git checkout "$apply_to"
  git stash apply
  git add -u
  git commit --amend --no-edit
  new_sha="$(git log --format="%H" -n 1)"
  git checkout "$current_branch"
  git rebase --onto "$new_sha" "$apply_to"
)

GitHub вище за течією .

Використання:

  • змінювати вихідний файл, не потрібно, git addякщо він вже знаходиться в РЕПО
  • git-amend-old $old_sha

Мені це подобається, --autosquashоскільки він не розчавлює інші непов'язані налаштування.


Дуже добре вирішити, це має бути варіантом за замовчуванням, git amendщоб застосувати зміни до певного комітету за допомогою поточного сховища, дуже розумно!
caiohamamura

5

Я вирішив це,

1) шляхом створення нового комітету зі змінами, які я хочу ..

r8gs4r commit 0

2) я знаю, які зобов'язання мені потрібно злити з ним. який є фіксом 3.

так, git rebase -i HEAD~4№4 являє собою 4 останніх комісії (тут команда 3 знаходиться на 4-му місці)

3) в інтерактивній базі останніх комітів буде розміщено внизу. це буде схоже,

pick q6ade6 commit 3
pick vr43de commit 2
pick ac123d commit 1
pick r8gs4r commit 0

4) тут нам потрібно переставити фіксацію, якщо ви хочете об'єднатися з певним. це має бути,

parent
|_child

pick q6ade6 commit 3
f r8gs4r commit 0
pick vr43de commit 2
pick ac123d commit 1

після переупорядкування вам потрібно замінити p pickна f( fixup об'єднається без повідомлення фіксації) або s( скріплення злиття з повідомленнями фіксування може змінити час виконання)

а потім збережіть своє дерево.

тепер злиття зроблено з існуючими комісіями.

Примітка. Це не бажаний метод, якщо ви не підтримуєте самостійно. якщо у вас великий розмір команди, його неприйнятний спосіб переписати дерево git може опинитися в конфліктах, про які вам відомо. якщо ви хочете підтримувати дерево у чистоті з меншими зобов’язаннями, можете спробувати це, і якщо його невелика команда в іншому випадку не бажана .....


Це приємне рішення, якщо ви не хочете робити живих модифікацій під час інтерактивної бази.
Дунатотатос

4

Найкращим варіантом є використання "Інтерактивної команди rebase" .

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

Кожен раз, коли ви перезаписуєте комісію, для кожної комісії буде створено нову SHA незалежно від того, зміст буде змінено чи ні! Ви повинні бути обережними, коли використовувати цю команду, оскільки це може мати різкі наслідки, особливо якщо ви працюєте у співпраці з іншими розробниками. Вони можуть почати працювати з вашими зобов’язаннями, поки ви відмовляєтесь від них. Після того, як ви змусите натиснути на комісії, вони не синхронізуються, і ви, можливо, дізнаєтесь пізніше у безладній ситуації. Тож будьте обережні!

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

Тепер, як використовувати цю команду?

git rebase -i <base> 

-iстенд "інтерактивний" . Зауважте, що ви можете виконати ребазування в неінтерактивному режимі. колишній:

#interactivly rebase the n commits from the current position, n is a given number(2,3 ...etc)
git rebase -i HEAD~n 

HEADвказує ваше поточне місцеположення (може бути також ім'ям філії або ввести SHA). ~nЧи означає «п beforeé, так HEAD~nбуде список" п "фіксацій до того, ви в даний момент.

git rebase має різні команди, такі як:

  • pабо pickпродовжувати виконувати так, як є.
  • rабо reword: зберігати вміст комітету, але змінювати повідомлення про фіксацію.
  • sабо squash: об'єднати зміни цього комітету в попередній комітет (зобов'язання над ним у списку).
  • ... і т.д.

    Примітка. Краще налагодити роботу Git з редактором коду, щоб зробити його простішим. Як, наприклад, якщо ви використовуєте візуальний код, ви можете додати такий git config --global core.editor "code --wait". Або ви можете шукати в Google, як пов’язати бажаний редактор коду з GIT.

Приклад git rebase

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

  1. Відображення поточних комісій:
    #This to show all the commits on one line
    $git log --oneline
    4f3d0c8 (HEAD -> documentation) docs: Add project description and included files"
    4d95e08 docs: Add created date and project title"
    eaf7978 (origin/master , origin/HEAD, master) Inital commit
    46a5819 Create README.md
    
  2. Тепер я використовую git rebaseдля зміни двох останніх повідомлень, які виконуються: $git rebase -i HEAD~2 Він відкриває редактор коду і показує це:

    pick 4d95e08 docs: Add created date and project title
    pick 4f3d0c8 docs: Add project description and included files
    
    # Rebase eaf7978..4f3d0c8 onto eaf7978 (2 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    ...
    

    Оскільки я хочу змінити повідомлення про фіксацію для цих 2 комітів. Тому я наберу rабо rewordзамість pick. Потім збережіть файл і закрийте вкладку. Зауважте, що rebaseвиконується в багатоетапному процесі, тому наступним кроком є ​​оновлення повідомлень. Зауважимо також, що коміти відображаються у зворотному хронологічному порядку, тому остання фіксація відображається в тому, а перша - у першому рядку тощо.

  3. Оновлення повідомлень: оновіть перше повідомлення:

    docs: Add created date and project title to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    зберегти та закрити Редагувати друге повідомлення

    docs: Add project description and included files to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    зберегти і закрити.

  4. Ви отримаєте подібне повідомлення до кінця ребазування: Successfully rebased and updated refs/heads/documentationце означає, що ви досягли успіху. Ви можете відобразити зміни:

    5dff827 (HEAD -> documentation) docs: Add project description and included files to the documentation "README.md"
    4585c68 docs: Add created date and project title to the documentation "README.md"
    eaf7978 (origin/master, origin/HEAD, master) Inital commit
    46a5819 Create README.md
    

    Я хочу, щоб це допомогло новим користувачам :).


2

Для мене це було для видалення деяких реєстрів з репо. Я спробував відмовитись і зіткнувся з тоною, здавалося б, незв'язаних конфліктів по дорозі, намагаючись переосмислити - продовжити. Не турбуйтеся намагатися переосмислити себе, скористайтеся інструментом BFG (варити інсталяцію bfg) на mac.


0

Якщо ви ще не натиснули комітети, ви можете повернутися до попередньої фіксації, використовуючи git reset HEAD^[1,2,3,4...]

Наприклад

git commit <file1> -m "Updated files 1 and 2"
git commit <file3> -m "Updated file 3"

На жаль, забув додати file2 до першого фіксації ...

git reset HEAD^1 // because I only need to go back 1 commit

git add <file2>

Це додасть file2 до першого фіксації.


0

Ну, це рішення може здатися дуже нерозумним, але може врятувати вас у певних умовах.

Мій друг просто натрапив на випадкове створення величезних файлів (чотири автоматично згенерованих файлів, розміром від 3 Гб до 5 ГБ кожен), а потім зробив додаткові додаткові коди, перш ніж зрозуміти проблему, яка більше git pushне працює!

Файли були внесені до списку, .gitignoreале після перейменування папки контейнера вони виявились та здійснені! А тепер поверх цього було ще кілька комітів коду, але pushвін працював назавжди (намагаючись завантажити ГБ даних!) І, нарешті, провалився через обмеження розміру файлів Github .

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

Отже, рішення, яке я придумав:

  1. Перейменуйте поточну папку git в ~/Project-old.
  2. Клоніруйте папку git знову з github (to ~/Project).
  3. Оформити замовлення до тієї ж філії.
  4. Вручну cp -rфайли з ~/Project-oldпапки в ~/Project.
  5. Переконайтеся, що масивні файли, які не потрібно перевіряти, mvвідредаговані та включені до них .gitignoreналежним чином.
  6. Також переконайтеся, що ви не перезаписуєте .gitпапку в недавно клонованій ~/Projectстарою. Ось де живуть журнали проблемної історії!
  7. Тепер перегляньте зміни. Це має бути об'єднання всіх останніх комітетів, виключаючи проблемні файли.
  8. Нарешті внесіть зміни, і це добре, щоб бути pushредактором.

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

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

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