كيفية تغيير اسم المؤلف واسم المفاتيح والبريد الإلكتروني للنزهات المتعددة في GIT؟

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

سؤال

كنت أكتب برنامج نصي بسيط في الكمبيوتر المدرسي، وارتكاب التغييرات في GIT (في Repo كان في Pendrive، المستنسخة من جهاز الكمبيوتر الخاص بي في المنزل). بعد عدة ارتكب، أدركت أنني كنت أرتكب أشياء كمستخدم الجذر.

هل هناك أي طريقة لتغيير مؤلف هذه الجميلات إلى اسمي؟

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

المحلول

يتطلب تغيير المؤلف (أو Committer) إعادة كتابة كل التاريخ. إذا كنت بخير مع ذلك وتعتقد أنه يستحق كل هذا العناء، فعليك التحقق من ذلك فرع فلتر جيت. وبعد تتضمن صفحة الرجل عدة أمثلة لتحصل عليها. لاحظ أيضا أنه يمكنك استخدام متغيرات البيئة لتغيير اسم المؤلف والتشغيل والتواريخ وما إلى ذلك - انظر قسم "متغيرات البيئة" من git man page..

على وجه التحديد، يمكنك إصلاح جميع أسماء المؤلفات الخاطئة ورسائل البريد الإلكتروني لجميع الفروع والعلامات مع هذا الأمر (المصدر: مساعدة جيثب):

#!/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

نصائح أخرى

باستخدام Rebase التفاعلي

يمكنك القيام بذلك

git rebase -i -p <some HEAD before all of your bad commits>

ثم قم بتمييز كل شيء سيئك ك "تحرير" في ملف Rebase. إذا كنت ترغب أيضا في تغيير الالتزام الأول، فعليك إضافته يدويا كطريق أول في ملف Rebase (اتبع تنسيق الأسطر الأخرى). ثم، عندما يطلب منك git تعديل كل الالتزام، افعل

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

تحرير أو مجرد إغلاق المحرر الذي يفتح، ثم القيام به

git rebase --continue

لمواصلة Rebase.

يمكنك تخطي فتح المحرر بالكامل هنا من خلال إلحاق --no-editبحيث يكون الأمر:

git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue

ارتكاب واحد

كما لاحظ بعض المعلقين، إذا كنت ترغب فقط في تغيير الالتزام الأحدث، فإن أمر Rebase غير ضروري. فقط تفعل

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

سيؤدي ذلك إلى تغيير هذا المؤلف إلى الاسم المحدد، ولكن سيتم تعيين المفتش من المستخدم الذي تم تكوينه في git config user.name و git config user.email. وبعد إذا كنت ترغب في تعيين المفاتيح إلى شيء تحدده، فسيحدد ذلك على كل من المؤلف والتشغيل:

 git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author

ملاحظة على دمج ارتكاب

كان هناك عيب طفيف في ردي الأصلي. إذا كان هناك أي دمج يرتكب بين التيار HEAD وخاصتك <some HEAD before all your bad commits>, ، ومن بعد git rebase سوف تتسطح لهم (وبالمناسبة، إذا كنت تستخدم طلبات سحب جيثب، فهناك طن من الدمج يرتكب في تاريخك). يمكن أن يؤدي ذلك في كثير من الأحيان إلى تاريخ مختلف للغاية (حيث قد يتم تحديث التغييرات المكررة ")، وفي أسوأ الحالات، يمكن أن تؤدي إلى git rebase اطلب منك حل تعارضات دمج صعبة (التي من المحتمل حلها بالفعل في ارتكاب الاندماج). الحل هو استخدام -p علم ل git rebase, ، الذي سيحافظ على بنية دمج تاريخك. manpage ل git rebase يحذر من استخدام -p و -i يمكن أن يؤدي إلى القضايا، ولكن في BUGS القسم الذي تقول "التحرير يرتكب وإعادة صياغة رسائل ارتكابها يجب أن تعمل بشكل جيد".

لقد اضفت -p إلى الأمر أعلاه. بالنسبة للقضية التي تغير فيها أحدث الالتزام، فإن هذه ليست مشكلة.

يمكنك أيضا القيام به:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

ملاحظة، إذا كنت تستخدم هذا الأمر في موجه أوامر Windows، فأنت بحاجة إلى استخدام " بدلا من ':

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

بطانة واحدة، ولكن كن حذرا إذا كان لديك مستودع متعدد المستخدمين - سيغير هذا الكل يلتزم أن يكون لها نفس المؤلف (جديد) وكيل.

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

مع Leverbreaks في السلسلة (وهو ممكن في باش):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

يحدث ذلك عندما لا يكون لديك موقع $ / .gitconfig تهيئة. قد إصلاح هذا كما:

git config --global user.name "you name"
git config --global user.email you@domain.com
git commit --amend --reset-author

تم اختباره مع الإصدار GIT 1.7.5.4

لالتزام واحد:

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

(المستخرجة من إجابة Asmeurer)

في حالة وجود ارتكاب عدد قليل فقط من المؤلفين السيئين، يمكنك القيام بذلك من الداخل git rebase -i باستخدام exec القيادة و --amend الالتزام، على النحو التالي:

git rebase -i HEAD~6 # as required

التي تقدم لك مع قائمة ارتكاب قابلة للتحرير:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

ثم أضف exec ... --author="..." خطوط بعد كل خطوط مع المؤلفين السيئين:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD

حفظ والخروج المحرر (لتشغيل).

قد يكون هذا الحل أطول من النوع من البعض الآخر، لكنه قابل للتحكم للغاية - أعرف بالضبط ما يرتكب يضربه.

شكرا ل Nampeurer للإلهام.

github لديه أ حل لطيف, ، وهو البرنامج النصي SHELT التالي:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

كما ذكر DocGnome المذكور، فإن تاريخ إعادة كتابة خطير وسيقطم مستودعات الآخرين.

ولكن إذا كنت تريد حقا أن تفعل ذلك وأنت في بيئة باش (لا توجد مشكلة في Linux، على Windows، فيمكنك استخدام GIT BASH، والتي يتم تزويدها بتثبيت GIT)، استخدم فرع فلتر جيت:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

لتسريع الأمور، يمكنك تحديد مجموعة من المراجعات التي تريد إعادة كتابةها:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

عند تولي الالتزام غير المكتسب من مؤلف آخر، هناك طريقة سهلة للتعامل مع هذا.

git commit --amend --reset-author

يمكنك استخدام هذا ك الاسم المستعار حتى تتمكن من القيام:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

أو لآخر 10 مرات:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

أضف إلى ~ / .gitconfig:

[alias]
    change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "

مصدر: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig.

آمل أن يكون مفيدا.

هذه نسخة أكثر وضعة من إصدار @ براين:

لتغيير المؤلف والتشغيل، يمكنك القيام بذلك (مع Leverbreaks في السلسلة الممكنة في BASH):

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

قد تحصل على واحدة من هذه الأخطاء:

  1. دليل المؤقت موجود بالفعل
  2. يربط بدءا يرجع / الأصلي موجود بالفعل
    (هذا يعني تشغيل فرع مرشح آخر سابقا على المستودع ويتم دعم مرجع الفرع الأصلي ثم في يرجع / الأصلي)

إذا كنت ترغب في إجبار المدى على الرغم من هذه الأخطاء، أضف --force علم:

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

تفسير القليل من -- --all قد تكون هناك حاجة إلى الخيار: إنه يجعل فرع المرشح يعمل على جميع المراجعات كل refs. (والتي تشمل جميع الفروع). هذا يعني، على سبيل المثال، إعادة كتابة العلامات أيضا واضحة على الفروع إعادة كتابة.

"خطأ" شائع هو استخدام HEAD بدلا من ذلك، مما يعني تصفية جميع المراجعات فقط الفرع الحالي. وبعد ثم لا توجد علامات (أو أيها أخرى) موجودة في الفرع إعادة كتابة.

  1. يركض git rebase -i <sha1 or ref of starting point>
  2. حدد كل يرتكب أنك تريد تغييرها edit (أو e)
  3. حلقة الأوامر التالية حتى تتم معالجة كل ارتكاب:

    git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>" ; git rebase --continue

سيؤدي ذلك إلى الحفاظ على جميع معلومات الالتزام الأخرى (بما في ذلك التواريخ). ال --reuse-message=HEAD يمنع الخيار محرر الرسائل من الإطلاق.

يمكنني استخدام ما يلي لإعادة كتابة المؤلف لمستودع كامل، بما في ذلك العلامات وجميع الفروع:

git filter-branch --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

ثم، كما هو موضح في صفحة رجل من فرع المرشح, ، قم بإزالة جميع الصور الأصلية المدعومة من قبل filter-branch (هذا مدمر، النسخ الاحتياطي أولا):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

أنا تكيفت هذا المحلول الذي يعمل عن طريق تناول بسيط author-conv-file (التنسيق هو نفسه واحد ل git-cvsimport.). إنه يعمل عن طريق تغيير جميع المستخدمين كما هو محدد في author-conv-file عبر جميع الفروع.

استخدمنا هذا بالتزامن مع cvs2git لترحيل مستودعنا من CVS إلى GIT.

أي عينة author-conv-file

john=John Doe <john.doe@hotmail.com>
jill=Jill Doe <jill.doe@hotmail.com>

النص:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all

لقد وجدت وسيلة الإصدارات المقدمة إلى العدوانية، خاصة إذا كنت تلتفأ بقع من المطورين الآخرين، فسيؤدي ذلك أساسا إلى سرقة رمزها بشكل أساسي.

يعمل الإصدار أدناه على جميع الفروع ويغير المؤلف والزخرف بشكل منفصل لمنع ذلك.

مجد إلى Leif81 لكل خيار.

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<youmail@somehost.ext>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<youmail@somehost.ext>";
fi
' -- --all
  1. التغيير الالتزام author name & email بواسطة Amend, ، ثم استبدال old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <author@email.com>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git push -f origin HEAD              # force push 
    
  2. طريق اخر Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <author@email.com>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    

يجب أن أشير إلى أنه إذا كانت المشكلة الوحيدة هي أن المؤلف / البريد الإلكتروني يختلف عن المعتاد، فهذه ليست مشكلة. الإصلاح الصحيح هو إنشاء ملف يسمى .mailmap في قاعدة الدليل مع خطوط مثل

Name you want <email you want> Name you don't want <email you don't want>

ومن ثم في، أوامر مثل git shortlog سوف تنظر في تلك الأسمتين ليكون هي نفسها (إلا إذا كنت تخبرهم على وجه التحديد عدم). يرى http://schacon.github.com/git/git-shortlog.html. للمزيد من المعلومات.

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

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

أ أمر واحد لتغيير المؤلف لآخر يرتكب:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

ملاحظات

  • ال --no-edit العلم يثبت git commit --amend لا يسأل تأكيدا إضافيا
  • عند استخدامها git rebase -i, ، يمكنك اختيار الالتزام يدويا أين لتغيير المؤلف،

الملف الذي تحريره سيظهر مثل هذا:

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

يمكنك بعد ذلك تعديل بعض الخطوط لمعرفة المكان الذي تريد تغيير المؤلف. يمنحك هذا أرضية متوسطة لطيفة بين الأتمتة والتحكم: ترى الخطوات التي سيتم تشغيلها، وبمجرد تطبيق كل شيء في وقت واحد.

إذا كنت المستخدم الوحيد لهذا المستودع، يمكنك إعادة كتابة التاريخ باستخدام سما git filter-branch (كما كتب سفيك)، أو git fast-export/git fast-import البرنامج النصي فلتر بالإضافة (كما هو موضح في المقالة المشار إليه في accnome الإجابة)، أو التفاعلية repase.. وبعد لكن أي من هؤلاء سيؤديون إلى تغيير المراجعات الذين تغيروا أولا في الالتزام فصاعدا؛ وهذا يعني مشكلة بالنسبة لأي شخص يستند بتغيراته في فرعك قبل إعادة كتابة.

التعافي

إذا لم يستند المطورون الآخرون عملهم في إصدار ما قبل إعادة الكتابة، فسيكون أبسط الحل لإعادة استنساخ (استنساخ مرة أخرى).

بدلا من ذلك يمكنهم محاولة git rebase --pull, ، والتي ستؤدي إلى الأمام إذا لم تكن هناك أي تغييرات في مستودعها، أو إعادة بناء فرعها على رأس ارتكاب إعادة كتابة (نريد أن نتجنب الدمج، حيث ستبقى مراجعا مسبقا إلى الأبد). كل هذا على افتراض أنهم ليسوا ليس لديهم عمل معقول؛ استعمال git stash لتخفيف التغييرات بعيدا.

إذا كان المطورون الآخرون يستخدمون فروع ميزة، و / أو git pull --rebase لا يعمل على سبيل المثال لأن المنبع لم يتم إعدادها، يجب عليهم repase. عملهم في قمة ما بعد إعادة الكتابة يرتكب. على سبيل المثال فقط بعد جلب تغييرات جديدة (git fetch)، ل master فرع يعتمد على / متشعب من origin/master, ، واحد يحتاج إلى تشغيل

$ git rebase --onto origin/master origin/master@{1} master

هنا origin/master@{1} هو ما قبل إعادة كتابة الدولة (قبل جلب)، انظر gitreviss.


الحل البديل سيكون لاستخدام إعادة حساب / استبدال / آلية، متوفرة في git منذ الإصدار 1.6.5. في هذا الحل، تقدم بدائل يرتكبها رسالة بريد إلكتروني خاطئة؛ ثم أي شخص يجلب "استبدال" يربط (شيء مثل fetch = +refs/replace/*:refs/replace/* refspec في المكان المناسب في هم .git/config) سيحصل على بدائل بشفافية، وأولئك الذين لا يحضرون أولئك يربطون يرون ارتكبهم قديمة.

الإجراء يذهب شيئا مثل هذا:

  1. ابحث عن كل ارتكاب بريد إلكتروني خاطئ، على سبيل المثال باستخدام

    $ git log --author=user@wrong.email --all
    
  2. لكل ارتكاب خاطئ، قم بإنشاء الالتزام بديلا، وإضافته إلى قاعدة بيانات الكائن

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  3. الآن بعد أن قمت بتصحيح الالتزام في قاعدة بيانات الكائنات، عليك أن تخبر GIT لاستبدال ارتكاب خطأ تلقائيا وشفاف عن طريق تصحيحه باستخدام git replace أمر:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  4. أخيرا، قم بإدراج جميع الاستبدال للتحقق مما إذا نجح هذا الإجراء

    $ git replace -l
    

    وتحقق مما إذا كانت البدائل تحدث

    $ git log --author=user@wrong.email --all
    

يمكنك بالطبع أتمتة هذا الإجراء ... حسنا، كل ما عدا باستخدام git replace التي لا تحتوي على وضع الدفعي (حتى الآن)، لذلك عليك استخدام حلقة Shell لذلك، أو استبدال "باليد".

لم تختبر! ymmv.

لاحظ أنك قد تواجه بعض الزوايا الخشنة عند استخدامها refs/replace/ آلية: إنها جديدة، وليس بعد اختبارها جيدا.

أسرع وأسهل طريقة للقيام بذلك هي استخدام وسيطة - exec من git rebase:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

سيؤدي ذلك إلى إنشاء قائمة LODO التي تبدو وكأنها:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

وهذا سيعمل جميعا تلقائيا، والذي يعمل عندما يكون لديك المئات من ارتكابها.

إذا ارتكبك الرغبة في الإصلاح هي الأحدث الأخرى، وفقط زوجين منها، يمكنك استخدام مزيج من git reset و git stash للعودة إلى ارتكابهم مرة أخرى بعد تكوين الاسم الصحيح والبريد الإلكتروني.

سيكون التسلسل شيء مثل هذا (لمدة 2 يرتكب خطأ، ولا توجد تغييرات معلقة):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a

إذا كنت تستخدم Eclipse مع EGIT، فهناك حلا سهلا للغاية.
الافتراض: لقد ارتكبت في فرع محلي "Local_master_User_x" الذي لا يمكن دفعه إلى فرع عن بعد "ماجستير" بسبب المستخدم غير صالح.

  1. الخروج من فرع النائية "ماجستير"
  2. حدد المشاريع / المجلدات / الملفات التي يحتوي عليها "local_macer_user_x" تغييرات
  3. انقر بزر الماوس الأيمن - استبدال مع - فرع - 'local_macer_user_x'
  4. ارتكب هذه التغييرات مرة أخرى، هذه المرة كمستخدم صحيح وفي الفرع المحلي "سيد"
  5. اضغط إلى "ماجستير" عن بعد

باستخدام Rebase التفاعلي، يمكنك وضع أمر تعديل بعد كل الالتزام الذي تريد تغييره. على سبيل المثال:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead

لاحظ أن مخازن git اثنين عناوين البريد الإلكتروني المختلفة، واحد ل committer. (الشخص الذي ارتكب التغيير) وآخر واحد ل مؤلف (الشخص الذي كتب التغيير).

لا يتم عرض معلومات المفاتيح في معظم الأماكن، ولكن يمكنك رؤيتها git log -1 --format=%cn,%ce (او استعمل show بدلا من log لتحديد ارتكاب معين).

أثناء تغيير مؤلف كتابك الأخير هو بسيط مثل git commit --amend --author "Author Name <email@example.com>", ، لا يوجد بطانة أو حجة واحدة للقيام بنفس الشيء لمعلومات المفاتيح.

الحل هو (مؤقتا، أم لا) تغيير معلومات المستخدم الخاصة بك، ثم تعديل الالتزام، والذي سيقوم بتحديث المفاتيح إلى معلوماتك الحالية:

git config user.email my_other_email@example.com 
git commit --amend

لقد واجهنا مشكلة اليوم حيث كان حرف UTF8 في اسم المؤلف يسبب مشكلة في خادم البناء، لذلك اضطررنا إلى إعادة كتابة التاريخ لتصحيح هذا. كانت الخطوات التي اتخذت:

الخطوة 1: تغيير اسم المستخدم الخاص بك في GIT لكل المستقبل، حسب التعليمات هنا:https://help.github.com/articles/setting-your-username-in-git/

الخطوة 2: تشغيل البرنامج النصي باش التالي:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="me@something.com"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force push the rewritten branches + tags to the remote
git push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

نظرة عامة سريعة: تسجيل الخروج مستودع الخاص بك إلى ملف TEMP، والخروج من جميع الفروع البعيدة، قم بتشغيل البرنامج النصي الذي سيعيد كتابة التاريخ، قم بإجراء عملية دفع للحالة الجديدة، وإخبار جميع زملائك بالقيام بإعادة التوطين للحصول على التغييرات.

كان لدينا مشكلة في تشغيل هذا على OS X لأنه افسدت بطريقة أو بأخرى نهايات الخط في ارتكاب الرسائل، لذلك كان علينا إعادة تشغيله على جهاز Linux بعد ذلك.

مشكلتك شائعة حقا. يرى "باستخدام MailMap لإصلاح قائمة المؤلفين في GIT"

من أجل البساطة، قمت بإنشاء برنامج نصي لتخفيف العملية: git-changemail.

بعد وضع هذا البرنامج النصي على طريقك، يمكنك إصدار أوامر مثل:

  • تغيير تطابق المؤلف في الفرع الحالي

    $ git changemail -a old@email.com -n newname -m new@email.com
    
  • تغيير المؤلف وu003Cbranch> وu003Cbranch2> وبعد يمر -f لتصفية الفرع للسماح بإعادة كتابة النسخ الاحتياطية

    $ git changemail -b old@email.com -n newname -m new@email.com -- -f &lt;branch> &lt;branch2>
    
  • إظهار المستخدمين الحاليين على الريبو

    $ git changemail --show-both
    

بالمناسبة، بعد إجراء تغييراتك، قم بتنظيف النسخة الاحتياطية من فرع المرشح مع: git-backup-نظيفة

إذا كنت المستخدم الوحيد لهذا الريبو أو لا تهتم بربط Repo للمستخدمين الآخرين، فعندئذ نعم. إذا دفعت هذه ترتكز، فهي موجودة حيث يمكن لأي مكان آخر الوصول إليها، فلا لا، إلا إذا كنت لا تهتم بتقسيم Repos الآخرين. المشكلة هي عن طريق تغيير هذه الالتزام، وسوف تولد Shas جديد سيؤدي إلى التعامل معها كملقم مختلف. عندما يحاول شخص آخر سحب في هذه التغييرات التي تم تغييرها، فإن التاريخ مختلف وكابوم.

هذه الصفحة http://inputvalidation.blogspot.com/2008/08/how-Change-Change-Git-Commit-Author.html. يصف كيفية القيام بذلك. (لم أحاول هذا حتى YMMV)

أريد أن أضيف مثالي أيضا. أريد أن أنشئ bash_function مع معلمة معينة.

هذا يعمل في Mint-Linux-17.3

# $1 => email to change, $2 => new_name, $3 => new E-Mail

function git_change_user_config_for_commit {

 # defaults
 WRONG_EMAIL=${1:-"you_wrong_mail@hello.world"}
 NEW_NAME=${2:-"your name"}
 NEW_EMAIL=${3:-"new_mail@hello.world"}

 git filter-branch -f --env-filter "
  if [ \$GIT_COMMITTER_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_COMMITTER_NAME='$NEW_NAME'
    export GIT_COMMITTER_EMAIL='$NEW_EMAIL'
  fi
  if [ \$GIT_AUTHOR_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_AUTHOR_NAME='$NEW_NAME'
    export GIT_AUTHOR_EMAIL='$NEW_EMAIL'
  fi
 " --tag-name-filter cat -- --branches --tags;
}
git rebase -i YOUR_FIRTS_COMMIT_SHA^

while true; do git commit --amend --author="Name Surname <email@example.com>" --no-edit && git rebase --continue; done

اضغط على ^ C # بعد الانتهاء من Rebase (ستستمر الحلقة في تحديث الالتزام الأخير)

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