Как изменить конкретный коммит?

Если целью является вызов функции some_func с классом в качестве аргумента, один ответ заключается в объявлении some_func в качестве декоратора класса. Обратите внимание, что декоратор класса вызывается после инициализации класса. Он будет передан классу, который оформляется в качестве аргумента.

def some_func(cls):
    # Do something
    print(f"The answer is {cls.x}")
    return cls # Don't forget to return the class

@some_func
class A:
    x = 1

Если вы хотите передать дополнительные аргументы в some_func, вы должны вернуть функцию из декоратора:

def some_other_func(prefix, suffix):
    def inner(cls):
        print(f"{prefix} {cls.__name__} {suffix}")
        return cls
    return inner

@some_other_func("Hello", " and goodbye!")
class B:
    x = 2

Декораторы классов могут быть скомпонованы, что приводит к их вызыванию в обратном порядке, которые они объявляются:

@some_func
@some_other_func("Hello", "and goodbye!")
class C:
    x = 42

. Результатом является:

# Hello C and goodbye!
# The answer is 42
1983
задан Lii 29 October 2018 в 10:35
поделиться

9 ответов

Вы можете использовать git rebase, например, если вы хотите изменить обратно для фиксации bbc643cd, запустите

$ git rebase --interactive 'bbc643cd^'

В редакторе по умолчанию измените от pick до edit в строке чей коммит вы хотите изменить. Внесите свои изменения, а затем передайте их с тем же сообщением, которое вы имели до:

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

, чтобы изменить фиксацию, и после этого

$ git rebase --continue

, чтобы вернуться к предыдущей фиксации головы.

ПРЕДУПРЕЖДЕНИЕ : обратите внимание, что это изменит SHA-1 этого коммита , а также всех потомков - другими словами, это переписывает историю с этого момента. Вы можете разбить репо, выполнив это , если нажмете команду git push --force

2579
ответ дан Paolo 29 October 2018 в 10:35
поделиться

Если вы еще не выдвинули коммиты, вы можете вернуться к предыдущему коммиту, используя git reset HEAD^[1,2,3,4...]

Например

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

Упс, забыли добавить файл2 в первый коммит ...

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

git add <file2>

Это добавит файл2 к первому коммиту.

0
ответ дан rharvey 29 October 2018 в 10:35
поделиться

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 upstream .

Использование:

  • Изменить файл
  • git-amend-old $old_sha

Мне нравится это над --autosquash, так как оно не раздавливает другие несвязанные исправления.

4
ответ дан Ciro Santilli 新疆改造中心996ICU六四事件 29 October 2018 в 10:35
поделиться

Чтобы получить неинтерактивную команду, поместите сценарий с этим содержимым в переменную 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>. Конечно, он все равно будет интерактивным, если вы столкнетесь с конфликтами.

6
ответ дан Pelle Nilsson 29 October 2018 в 10:35
поделиться

На основе Документации

Исправление сообщения более старых или сообщений о множественной фиксации

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.

Сохраните и закройте файл списка коммитов, появится новый редактор для вас, чтобы изменить ваше сообщение коммита , измени сообщение коммита и сохрани.

Finaly Force-push исправленных коммитов.

git push --force
9
ответ дан justMe 29 October 2018 в 10:35
поделиться

Если по какой-то причине вам не нравятся интерактивные редакторы, вы можете использовать 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 (включительно)». То есть, Commit2 и Commit3, полностью исключая старый Commit1. Вы можете просто выбрать их, но так проще.

Не забудьте почистить свои ветви!

git branch -d amending
16
ответ дан FeepingCreature 29 October 2018 в 10:35
поделиться

Пришел к такому подходу (и он, вероятно, точно такой же, как использование интерактивной перебазировки), но для меня это довольно просто.

Примечание: я представляю этот подход для иллюстрации того, что вы можете сделать, а не для повседневной альтернативы. Так как в нем много шагов (и, возможно, несколько предостережений).

Скажем, вы хотите изменить коммит 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)

Перебазировать 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 при ребазинге.

Примечание: все хеши коммитов меняются, начиная с коммита, который мы изначально намеревались изменить.

7
ответ дан Olga 29 October 2018 в 10:35
поделиться

Интерактивный ребаз с --autosquash - это то, что я часто использую, когда мне нужно исправить предыдущие коммиты глубже в истории. Это существенно ускоряет процесс, который иллюстрирует ответ ZelluX, и особенно удобно, когда вам нужно отредактировать более одного коммита.

Из документации:

--autosquash

Когда сообщение журнала фиксации начинается с «squash!…» (Или «fixup!…»), И там это коммит, название которого начинается с того же самого…, автоматически изменяйте список задач rebase -i, чтобы коммит, помеченный для сквошинга, пришел сразу после коммита, подлежащего изменению

Предположим, у вас есть история это выглядит следующим образом:

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

и у вас есть изменения, которые вы хотите изменить в Commit2, затем зафиксируйте свои изменения, используя

$ git commit -m "fixup! Commit2"

, в качестве альтернативы вы можете использовать commit-sha вместо сообщение коммита, так что "fixup! e8adec4 или даже просто префикс сообщения коммита.

Затем инициируйте интерактивную перебазировку при коммите до

$ git rebase e8adec4^ -i --autosquash

, ваш редактор откроется с коммитами, уже правильно упорядоченными

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

, все что вам нужно сделать, это сохранить и выйти

67
ответ дан thrau 29 October 2018 в 10:35
поделиться

Наилучший вариант состоит в том, чтобы использовать "Интерактивная переосновная команда" .

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

Каждый раз, когда Вы повторно основываете фиксацию, новый SHA будет создан для каждой фиксации независимо от содержания, будет изменен или нет! Необходимо быть осторожными, когда использовать эту причину команды, она может иметь решительные последствия особенно, если Вы работаете в сотрудничестве с другими разработчиками. Они могут начать работать с Вашей фиксацией, в то время как Вы повторно основываете некоторых. После принуждения для продвижения фиксаций, которыми они будут вне синхронизации, и можно узнать позже в грязной ситуации. Так будьте осторожны!

рекомендуется создать backup ответвление прежде, чем повторно базироваться поэтому каждый раз, когда Вы находите вещи из-под контроля, можно возвратиться назад к предыдущему состоянию.

Теперь, как использовать эту команду?

git rebase -i <base> 

-i обозначают [1 160] "интерактивный" . Обратите внимание, что можно выполнить переоснову в неинтерактивном режиме. исключая:

#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 означает "n beforeГ©, таким образом HEAD~n будет список фиксаций "n" перед той, Вы в настоящее время включены.

git rebase имеет другую команду как:

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

    Примечание: лучше заставить Мерзавца, работающего с Вашим редактором кода делать вещи более простыми. Как, например, если Вы используете визуальный код, можно добавить как это git config --global core.editor "code --wait". Или можно искать в Google, как связать Вас, предпочел Ваш редактор кода с МЕРЗАВЦЕМ.

Пример [1 121]

я хотел изменить последние 2 фиксации, которые я сделал так, я обрабатываю как это:

  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 для изменения 2 последних сообщений фиксаций: $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 вместо [1 126]. Затем Сохраните файл и закройте вкладку. Обратите внимание, что 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
    

    я желаю, чтобы это могло помочь новым пользователям :).

1
ответ дан 22 November 2019 в 19:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: