كيفية تغيير مؤلف الالتزام لالتزام واحد محدد؟

StackOverflow https://stackoverflow.com/questions/3042437

  •  27-09-2019
  •  | 
  •  

سؤال

أريد تغيير مؤلف واحد لالتزام محدد في التاريخ. إنه ليس الالتزام الأخير.

أنا أعرف هذا السؤال - كيف يمكنني تغيير مؤلف الالتزام في Git؟

لكنني أفكر في شيء ما ، حيث حدد الالتزام بالتجزئة أو التثبيت القصير.

هل كانت مفيدة؟

المحلول

Rebase التفاعلي خارج نقطة في وقت سابق من التاريخ من الالتزام الذي تحتاج إلى تعديله (git rebase -i <earliercommit>). في قائمة الالتزامات التي يجري الانتهاء ، قم بتغيير النص من pick ل edit بجانب تجزئة الشخص الذي تريد تعديله. ثم عندما يطالبك Git بتغيير الالتزام ، استخدم هذا:

git commit --amend --author="Author Name <email@address.com>"

على سبيل المثال ، إذا كان تاريخ الالتزام الخاص بك A-B-C-D-E-F مع F مثل HEAD, ، وتريد تغيير مؤلف من C و D, ، عندها ...

  1. حدد git rebase -i B (إليك مثال على ما ستراه بعد تنفيذ git rebase -i B أمر)
    • إذا كنت بحاجة إلى التعديل A, ، استعمال git rebase -i --root
  2. تغيير الخطوط لكليهما C و D من عند pick ل edit
  3. بمجرد بدء Rebase ، سوف يتوقف أولاً في C
  4. انت ترغب git commit --amend --author="Author Name <email@address.com>"
  5. ثم git rebase --continue
  6. سوف يتوقف مرة أخرى في D
  7. ثم تفعل git commit --amend --author="Author Name <email@address.com>" تكرارا
  8. git rebase --continue
  9. سوف يكتمل Rebase.
  10. يستخدم git push -f لتحديث أصلك مع الالتزامات المحدثة.

نصائح أخرى

ال إجابة مقبولة على هذا السؤال ، يوجد استخدام ذكي رائع لـ Rebase التفاعلي ، لكنه للأسف يعرض تعارضات إذا كان الالتزام الذي نحاول تغييره لمؤلف كتابتهما في فرع تم دمجه لاحقًا. بشكل عام ، لا يعمل عند التعامل مع الفوضى التاريخ.

نظرًا لأنني خائف من تشغيل البرامج النصية التي تعتمد على إعداد متغيرات البيئة وإعدادها لإعادة كتابة تاريخ GIT ، فإنني أكتب إجابة جديدة بناءً على هذا المشنور الذي يشبه هذا الجواب ولكن أكثر اكتمالا.

يتم اختبار ما يلي والعمل ، على عكس الإجابة المرتبطة. افترض أن وضوح المعرض 03f482d6 هو الالتزام الذي نحاول استبداله ، و 42627abe هو الالتزام مع المؤلف الجديد.

  1. الخروج عن الالتزام الذي نحاول تعديله.

    git checkout 03f482d6
    
  2. اجعل المؤلف يغير.

    git commit --amend --author "New Author Name <New Author Email>"
    

    الآن لدينا التزام جديد مع هاش يفترض أنه 42627abe.

  3. الخروج من الفرع الأصلي.

  4. استبدال الالتزام القديم مع واحد جديد محليا.

    git replace 03f482d6 42627abe
    
  5. أعد كتابة كل الالتزامات المستقبلية بناءً على الاستبدال.

    git filter-branch -- --all
    
  6. إزالة الاستبدال للنظافة.

    git replace -d 03f482d6
    
  7. ادفع التاريخ الجديد (استخدم فقط -القوة إذا فشل أدناه ، وفقط بعد التحقق من العقل git log و/أو git diff).

    git push --force-with-lease
    

بدلاً من 4-6 يمكنك فقط إعادة التزام جديد:

git rebase -i 42627abe

الوثائق github تحتوي على البرنامج النصي الذي يحل محل معلومات الالتزام لجميع الالتزامات في فرع.

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
  • أعد تعيين بريدك الإلكتروني إلى التكوين على مستوى العالم:

    git config --global user.email example@email.com

  • الآن أعد ضبط مؤلف التزامك دون التعديل المطلوب:

    git commit --amend --reset-author --no-edit

يمكنك تغيير مؤلف الالتزام الأخير باستخدام الأمر أدناه.

git commit --amend --author="Author Name <email@address.com>"

ومع ذلك ، إذا كنت ترغب في تغيير أكثر من واحد يرتكب اسم المؤلف ، فهذا أمر صعب بعض الشيء. تحتاج إلى بدء Rebase التفاعلي ثم يرتكب Mark كتحرير ثم قم بتمهيدها واحدًا تلو الآخر والانتهاء.

ابدأ في إعادة التدوير git rebase -i. سوف تظهر لك شيئًا كهذا.

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

غير ال pick الكلمة الرئيسية ل edit للالتزامات التي تريد تغيير اسم المؤلف.

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

ثم أغلق المحرر. للمبتدئين ، ضرب Escape ثم اكتب :wq وضرب Enter.

ثم سترى المحطة الخاصة بك مثل شيء لم يحدث. في الواقع أنت في منتصف ريباس التفاعلي. حان الوقت الآن لتعديل اسم مؤلف الالتزام باستخدام الأمر أعلاه. سيفتح المحرر مرة أخرى. استقال ومواصلة Rebase مع git rebase --continue. كرر نفس الشيء عن عدد الالتزام الذي تريد تحريره. يمكنك التأكد من انتهاء Rebase التفاعلي عند الحصول على No rebase in progress? رسالة.

الإجابات في السؤال الذي ربطته هي إجابات جيدة وتغطي موقفك (السؤال الآخر أكثر عمومية لأنه يتضمن إعادة كتابة ارتباطات متعددة).

كذريعة لتجربتها git filter-branch, ، كتبت نصًا لإعادة كتابة اسم المؤلف و/أو البريد الإلكتروني للمؤلف لالتزام معين:

#!/bin/sh

#
# Change the author name and/or email of a single commit.
#
# change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]]
#
#     If -f is supplied it is passed to "git filter-branch".
#
#     If <branch-to-rewrite> is not provided or is empty HEAD will be used.
#     Use "--all" or a space separated list (e.g. "master next") to rewrite
#     multiple branches.
#
#     If <new-name> (or <new-email>) is not provided or is empty, the normal
#     user.name (user.email) Git configuration value will be used.
#

force=''
if test "x$1" = "x-f"; then
    force='-f'
    shift
fi

die() {
    printf '%s\n' "$@"
    exit 128
}
targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit"
br="${2:-HEAD}"

TARG_COMMIT="$targ"
TARG_NAME="${3-}"
TARG_EMAIL="${4-}"
export TARG_COMMIT TARG_NAME TARG_EMAIL

filt='

    if test "$GIT_COMMIT" = "$TARG_COMMIT"; then
        if test -n "$TARG_EMAIL"; then
            GIT_AUTHOR_EMAIL="$TARG_EMAIL"
            export GIT_AUTHOR_EMAIL
        else
            unset GIT_AUTHOR_EMAIL
        fi
        if test -n "$TARG_NAME"; then
            GIT_AUTHOR_NAME="$TARG_NAME"
            export GIT_AUTHOR_NAME
        else
            unset GIT_AUTHOR_NAME
        fi
    fi

'

git filter-branch $force --env-filter "$filt" -- $br

الالتزام من قبل:

enter image description here

لإصلاح المؤلف لجميع الالتزامات ، يمكنك تطبيق الأمر من إجابة @Amber:

git commit --amend --author="Author Name <email@address.com>"

أو لإعادة استخدام اسمك والبريد الإلكتروني يمكنك فقط الكتابة:

git commit --amend --author=Eugen

الالتزام بعد الأمر:

enter image description here

على سبيل المثال لتغيير كل شيء يبدأ من 4025621:

enter image description here

انت مجبر ان تركض:

git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621

ملاحظة: لتضمين مؤلف يحتوي على مساحات مثل الاسم وعنوان البريد الإلكتروني ، يجب أن يكون المؤلف محاطًا باقتباسات هرب. علي سبيل المثال:

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <foo@bar.com>\"" 4025621

أو أضف هذا الاسم المستعار إلى ~/.gitconfig:

[alias]
    reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --

ثم الركض:

git reauthor 4025621 Eugen

هناك خطوة إضافية ل إجابة العنبر إذا كنت تستخدم مستودعًا مركزيًا:

git push -f لفرض تحديث المستودع المركزي.

كن حذرًا من عدم وجود الكثير من الأشخاص الذين يعملون على نفس الفرع لأنه يمكن أن يدمر الاتساق.

عند القيام به git rebase -i هناك هذا الشيء المثير للاهتمام في المستند:

إذا كنت ترغب في طي اثنين أو أكثر من الالتزام في واحد ، استبدل الأمر "pick" لصالح الثاني واللاحق مع "squash" أو "fixup". إذا كان لدى الالتزامات مؤلفين مختلفين ، فسوف يعزى الالتزام المطوي إلى مؤلف الالتزام الأول. رسالة الالتزام المقترحة للالتزام المطوي هي تسلسل رسائل الالتزام بالالتزام الأول وأولئك الذين لديهم "squash" أمر ، ولكن يحذف رسائل الالتزام بالالتزامات مع "fixup" أمر.

  • إذا كان لديك تاريخ A-B-C-D-E-F,
  • وتريد تغيير الالتزامات B و D (= 2 يرتكب) ،

ثم يمكنك أن تفعل:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • إنشاء ارتباطات فارغة (واحدة لكل ملزمة):
    • أنت بحاجة إلى رسالة لغرض Rebase
    • git commit --allow-empty -m "empty"
  • ابدأ عملية Rebase
    • git rebase -i B^
    • B^ يختار الوالد B.
  • سترغب في وضع التزام فارغ واحد قبل كل التزام بالتعديل
  • سترغب في التغيير pick ل squash لأولئك.

مثال على ما git rebase -i B^ سوف أعطيك:

pick sha-commit-B some message
pick sha-commit-C some message
pick sha-commit-D some message
pick sha-commit-E some message
pick sha-commit-F some message
# pick sha-commit-empty1 empty
# pick sha-commit-empty2 empty

تغيير ذلك إلى:

# change commit B's author
pick sha-commit-empty1 empty
squash sha-commit-B some message
# leave commit C alone
pick sha-commit-C some message
# change commit D's author
pick sha-commit-empty2 empty
squash sha-commit-D some message
# leave commit E-F alone
pick sha-commit-E some message
pick sha-commit-F some message

سيطالبك بتحرير الرسائل:

# This is a combination of 2 commits.
# The first commit's message is:

empty

# This is the 2nd commit message:

...some useful commit message there...

ويمكنك فقط إزالة الأسطر القليلة الأولى.

في تعزيز ل يوجين كونكوف الاستجابة ، للبدء من التزام الجذر ، والاستخدام --root علَم. ال --no-edit العلم مفيد أيضًا

git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"

إذا كان ما تحتاج إلى تغييره هو مؤلف الالتزام الأخير ولا يستخدم أي شخص آخر مستودعك ، فيمكنك التراجع عن التزامك الأخير بـ:

git push -f origin last_commit_hash:branch_name 

قم بتغيير اسم المؤلف لالتزامك بـ:

git commit --amend --author "type new author here"

الخروج من المحرر الذي يفتح ويدفع مرة أخرى الكود الخاص بك:

git push

هناك أيضًا نهج كسول لهذه المشكلة ، خاصةً إذا كان لديك أكثر من تلتزم تريد تغييره. في حالتي ، كان لديّ فرع جديد به العديد من الالتزامات مع مؤلف خاطئ ، فما الذي ساعدني:

انتقل إلى فرعك الأصلي:

git checkout develop

إنشاء فرع جديد منه:

git checkout -b myFeature develop 

قم بدمجها دون الالتزام بالمعلومات كالتزام واحد:

git merge --no-commit --squash branchWrongAuthor

قد ترغب أيضًا في تنظيم التغييرات:

git stage .

قم بتغيير اسم المؤلف وارتكاب التغييرات:

git commit --amend --author "New Author Name <New Author Email>" -m "new feature added"

وهذا كل شيء ، يمكنك دفع التغييرات.

git push

يمكنك حذف الفرع مع مؤلف خاطئ بعد ذلك.

إذا كان الالتزام الذي تريد تغييره ليس الالتزام الأخير ، ثم اتبع الخطوات أدناه. إذا كان التزامك في فرع مختلف ، فقم بالتبديل أولاً إلى هذا الفرع.

git checkout branch_name

ابحث عن الالتزام قبل الالتزام الذي تريد تغييره والعثور على تجزئة. ثم إصدار قيادة Rebase.

git rebase -i -p hash من الالتزام

ثم سيتم فتح محرر وإدخال "تحرير" للالتزامات التي تريد تغييرها. اترك الآخرين مع خيار "اختيار" الافتراضي. بمجرد تغييره ، أدخل مفتاح "ESC" و WQ! للخروج.

ثم إصدار أمر ارتكاب GIT مع خيار التعديل.

GIT Commice-exend-Author = "username email"-no-edit

ثم إصدار الأمر التالي.

git rebase - -continue

بمجرد تحديث مؤلف الالتزام في المستودع المحلي ، ادفع التغييرات إلى المستودع البعيد.

خطوات لإعادة تسمية اسم المؤلف بعد دفع الالتزام

  1. النوع الأول "سجل git" للحصول على معرف الالتزام والمزيد من التفاصيل
  2. git rebase i ad ~ 10 (10 هو الالتزام الكلي للعرض على Rebase)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. ثم اكتب "git rebase - -continue" أو "git rebase -cort" حسب حاجتك

    • الآن فتحت نافذة إرادتك Rebase ، انقر فوق مفتاح "I" من لوحة المفاتيح
    • بعد ذلك ، ستحصل على قائمة بالالتزامات إلى 10 [لأننا مررنا 10 ارتكاب أعلاه] كما هو موضح أدناه

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. أنت الآن بحاجة إلى إضافة أمر أدناه أسفل الالتزام الذي تريد تحريره ، كما أدناه

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <author.name@mail.com>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <author.name@mail.com>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <author.name@mail.com>'

    1. هذا كل شيء ، الآن اضغط على ESC ،: WQ وأنت جميعًا

    2. ثم Git Push Origin Head: اسم الفرع -F [يرجى الاعتناء بـ -F PORTS PUSH

    مثل git push -f أو git push origin HEAD: dev -f

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top