सवाल गिट में लेखक और कम्यूटर नाम और एकाधिक कामों का ई-मेल कैसे बदलें?


मैं स्कूल कंप्यूटर में एक साधारण लिपि लिख रहा था, और गिट में बदलाव कर रहा था (एक रेपो में जो मेरे पेंड्रिव में था, घर पर मेरे कंप्यूटर से क्लोन किया गया था)। कई काम करने के बाद मुझे एहसास हुआ कि मैं मूल उपयोगकर्ता के रूप में सामान कर रहा था।

क्या इन कामों के लेखक को मेरे नाम पर बदलने का कोई तरीका है?


2004
2018-04-15 03:09


मूल


प्रश्न: गिट फ़िल्टर-शाखा का उपयोग करते हुए SHA1 को पिछले टैग, संस्करणों और ऑब्जेक्ट्स के लिए संरक्षित करता है? या लेखक नाम बल बदलकर संबंधित SHA1 को बदल देगा? - AndyL
हेश हां बदल जाएगा - Not Available
आश्चर्यजनक रूप से, मैंने एक छोटी सी लिपि बनाई जिसने अंततः मेरे लिए मूल कारण तय किया। gist.github.com/tripleee/16767aa4137706fd896c - tripleee
@impinball सवाल की उम्र शायद ही प्रासंगिक है। एक नया डुप्लिकेट प्रश्न बनाना सवाल से बाहर है। मुझे लगता है कि मैं एक ऐसा प्रश्न बना सकता हूं जो इस विशेष उत्तर से पूछता है लेकिन मुझे पूरी तरह से विश्वास नहीं है कि यह सभी दृश्यता प्राप्त करेगा। ऐसा नहीं है कि यहां गिट प्रश्नों की कमी है ... खुशी है कि मैं मदद कर सकता हूं, वैसे भी। - tripleee
गिटहब के लिए विशेष लिपि है: help.github.com/articles/changing-author-info - Timur Bernikowich


जवाब:


लेखक (या कमिटर) को बदलने के लिए सभी इतिहास को दोबारा लिखना होगा। यदि आप इसके साथ ठीक हैं और सोचें कि यह इसके लायक है तो आपको जांच करनी चाहिए गिट फ़िल्टर-शाखा। मैन पेज में आपको शुरू करने के लिए कई उदाहरण शामिल हैं। यह भी ध्यान रखें कि आप लेखक, कमिटर, तिथियों इत्यादि के नाम को बदलने के लिए पर्यावरण चर का उपयोग कर सकते हैं - "पर्यावरण चर" अनुभाग देखें गिट मैन पेज

विशेष रूप से, आप सभी गलत लेखक नाम और ईमेल को ठीक कर सकते हैं सभी शाखाओं और टैग के लिए इस आदेश के साथ (स्रोत: गिटहब मदद):

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

801
2018-04-15 03:16



इसके लिए गितूब की एक सार्वजनिक लिपि है help.github.com/articles/changing-author-info और यह बहुत अच्छा काम करता है! - rodowi
स्क्रिप्ट निष्पादित करने के बाद आप "गिट अपडेट-रेफ-डी रेफ / मूल / रेफ / हेड / मास्टर" निष्पादित करके बैकअप शाखा को हटा सकते हैं। - D.R.
@rodowi, यह मेरे सभी कामों को डुप्लिकेट करता है। - Rafael Barros
@RafaelBarros लेखक की जानकारी (इतिहास में किसी और चीज की तरह) प्रतिबद्ध की शा कुंजी का हिस्सा है। इतिहास में कोई भी बदलाव एक पुनर्लेख है जो सभी आईडी के लिए नई आईडी की ओर जाता है। तो किसी साझा रेपो पर फिर से लिखना न करें या सुनिश्चित करें कि सभी उपयोगकर्ता इसके बारे में जानते हैं ... - johannes
हल हल git push --force --tags origin HEAD:master - Matteo Contrini


इंटरेक्टिव रीबेस का उपयोग करना

तुम यह कर सकते थे

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

फिर अपने सभी बुरे कामों को रीबेस फ़ाइल में "संपादित करें" के रूप में चिह्नित करें। यदि आप अपनी पहली प्रतिबद्धता भी बदलना चाहते हैं, तो आपको इसे रीबेस फ़ाइल में मैन्युअल रूप से पहली पंक्ति के रूप में जोड़ना होगा (अन्य पंक्तियों के प्रारूप का पालन करें)। फिर, जब गिट आपको प्रत्येक प्रतिबद्धता में संशोधन करने के लिए कहता है, तो करें

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

खुलने वाले संपादक को संपादित या बंद करें, और फिर करें

git rebase --continue

रिबेस जारी रखने के लिए।

आप संलग्न करके संपादक को पूरी तरह से खोलना छोड़ सकते हैं --no-edit ताकि आदेश होगा:

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

एकल प्रतिबद्धता

चूंकि कुछ टिप्पणीकारों ने ध्यान दिया है, अगर आप सबसे हालिया प्रतिबद्धता को बदलना चाहते हैं, तो रिबेस कमांड आवश्यक नहीं है। बस करो

 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, जो आपके इतिहास की विलय संरचना को संरक्षित रखेगा। के लिए मैनपेज git rebase चेतावनी देता है कि उपयोग कर रहा है -p तथा -i मुद्दों का कारण बन सकता है, लेकिन में BUGS अनुभाग में यह कहता है "संपादन करना और उनके प्रतिबद्ध संदेशों को दोबारा जोड़ना ठीक काम करना चाहिए।"

मैंने जोड़ लिया है -p उपरोक्त आदेश के लिए। इस मामले के लिए जहां आप सबसे हालिया प्रतिबद्धता को बदल रहे हैं, यह कोई मुद्दा नहीं है।


1417
2017-08-24 03:08



हालांकि अजीब प्रतिबद्धता के लिए बढ़िया - उपयोगी है अगर आप जोड़ रहे हैं और लेखक को बदलना भूल जाते हैं - mloughran
सामान्य एक-गलती फिक्स के लिए उपयोगकेस का उल्लेख करने के लिए +1: गिट प्रतिबद्ध --amend --author = उपयोगकर्ता नाम - Nathan Kidd
यह सही है, मेरा सबसे आम उपयोग यह है कि मैं किसी अन्य कंप्यूटर पर बैठता हूं और लेखक को सेट करना भूल जाता हूं और इस प्रकार आमतौर पर ठीक करने के लिए <5 काम करता है या ऐसा होता है। - Zitrax
git commit --amend --reset-author एक बार भी काम करता है user.name तथा user.email सही ढंग से कॉन्फ़िगर किया गया है। - pts
लेखक के बारे में सभी जानकारी के बाद लिखें <commit> का उपयोग करते हुए user.name तथा user.email से ~/.gitconfig: भागो git rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit'बचाओ, छोड़ो। संपादित करने की कोई ज़रूरत नहीं है! - ntc2


आप यह भी कर सकते हैं:

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

566
2018-05-15 19:15



एनवी-फिल्टर का उपयोग आसान समाधान का उपयोग नहीं कर रहा है? यकीन नहीं है कि यह और वोट क्यों मिल रहा है, तो। - stigkj
फिर लिंक टूटा हुआ है। हम इन परिवर्तनों को किसी अन्य भंडार में कैसे दबा सकते हैं? - Russell
एनवी-फिल्टर सभी कामों को बदल देगा। यह समाधान एक सशर्त की अनुमति देता है। - user208769
"A previous backup already exists in refs/original/ Force overwriting the backup with -f" क्षमा करें लेकिन कहाँ -f -फ्लग इस स्क्रिप्ट को दो बार निष्पादित करने जा रहा है। असल में ब्रायन के जवाब में, फिल्टर-शाखा समाधान के ठीक बाद परेशानी के बारे में खेद है। - hhh
@ user208769 env-filter भी एक सशर्त की अनुमति देता है; मेरा जवाब देखें :-) - stigkj


एक लाइनर, लेकिन सावधान रहें यदि आपके पास बहु-उपयोगकर्ता भंडार है - यह बदलेगा सब एक ही (नया) लेखक और कमिटर होने का काम करता है।

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

स्ट्रिंग में लाइनब्रेक्स के साथ (जो बाश में संभव है):

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

483
2018-04-15 03:22



हां, लेकिन कमिटर का नाम / ईमेल मत भूलना। मेरे लिए क्या काम किया गया था git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; GIT_COMMITER_NAME='Newname'; GIT_COMMITTER_EMAIL='newemail';" HEAD अन्यथा गिट पुराने नाम का एक कमिटर के रूप में ट्रैक रखेगा! - Olivier Verdier
@ ओलिवियर आपके पास GIT_COMMITER_NAME -> GIT_COMMITTER_NAME पर एक टाइपो है - Filipe Correia
यह शुरुआती एक सहित मेरे लिए सभी काम करता है। - Vincent
यदि आप निर्दिष्ट करते हैं तो यह सभी कामों को फिर से लिखता है HEAD आदेश के अंत में? - Nick Volynkin
यह मेरे बिटबकेट भंडार, किसी भी विचार के लिए काम नहीं करता है? मैं एक करता हूँ git push --force --tags origin 'refs/heads/*' सलाह दी गई कमांड के बाद - ujsgeyrr1f0d0d0r0h1h0j0j_juj


ऐसा तब होता है जब आपके पास $ HOME / .gitconfig प्रारंभ नहीं होता है। आप इसे इस प्रकार ठीक कर सकते हैं:

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

गिट संस्करण 1.7.5.4 के साथ परीक्षण किया


202
2018-02-16 09:46



यह आखिरी प्रतिबद्धता पर वास्तव में अच्छा काम करता है। अच्छा और सरल नहीं करता है है वैश्विक परिवर्तन होने के लिए --local भी काम करता है - Ben
git commit --amend --reset-author --no-edit - mafrosis


एक ही प्रतिबद्धता के लिए:

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

(एस्मेयर के जवाब से निकाला गया)


180
2018-04-26 22:50



लेकिन यह केवल तभी है जब यह सबसे हालिया प्रतिबद्धता है - Richard
इसके अनुसार git help commit, git commit --amend "वर्तमान शाखा की नोक" (जो हेड है) पर प्रतिबद्धता को बदलता है। यह आमतौर पर सबसे हालिया प्रतिबद्धता है, लेकिन आप इसे पहले से ही कोई प्रतिबद्धता बना सकते हैं जाँच से बाहर जो प्रतिबद्ध है git checkout <branch-name> या git checkout <commit-SHA>। - Rory O'Kane
लेकिन यदि आप ऐसा करते हैं, तो सभी काम जो पहले से ही माता-पिता के रूप में करते हैं, गलत प्रतिबद्धता को इंगित करेंगे। उस बिंदु पर फ़िल्टर-शाखा का उपयोग करने के लिए बेहतर है। - John Gietzen
@ जॉन गेटजेन: आप इसे वापस करने के लिए बदले गए उस पर वापस काम कर सकते हैं। हालांकि, यदि आप कर रहे हैं> 1 प्रतिबद्ध, तो जैसा कि बताया गया है, फ़िल्टर-शाखा शायद बहुत आसान हो जाएगी। - Thanatos
ध्यान दें कि यह केवल परिवर्तन ही प्रतिबद्ध है author और नहीं committer - Nick Volynkin


ऐसे मामले में जहां शीर्ष कुछ काम करने वाले बुरे लेखकों के पास है, आप इसे सब कुछ कर सकते हैं 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

सहेजें और संपादक से बाहर निकलें (चलाने के लिए)।

यह समाधान कुछ अन्य लोगों की तुलना में टाइप करने के लिए लंबा हो सकता है, लेकिन यह अत्यधिक नियंत्रित है - मुझे पता है कि यह वास्तव में क्या हिट करता है।

प्रेरणा के लिए @asmeurer के लिए धन्यवाद।


152
2017-12-08 17:05



निश्चित रूप से भयानक। क्या आप repo की स्थानीय कॉन्फ़िगरेशन में user.name और user.email को सेट करके इसे छोटा कर सकते हैं, और फिर प्रत्येक पंक्ति केवल तभी होती हैexec git commit --amend --reset-author -C HEAD ? - Andrew
@Andrew --reset-लेखक बस ठीक काम करता है। - Boggin
फ़िल्टर-शाखा का उपयोग करने के लिए कैननिकल उत्तर, बस मेरे लिए रेफरी / हेड / मास्टर हटा दिया गया। तो अपने नियंत्रण योग्य, संपादन योग्य समाधान के लिए +1। धन्यवाद! - jmtd
आप क्यों शुरू करते हैं Someone else's commitके बजाय my bad commit 1? मैंने अभी कोशिश की HEAD^^ पिछले 2 कामों में संशोधन करने के लिए, और यह पूरी तरह से ठीक काम किया। - fredoverflow
की जगह git rebase -i HEAD^^^^^^ आप भी लिख सकते हैं git rebase -i HEAD~6 - Patrick Schlüter


गिथब एक है अच्छा समाधान, जो निम्न शैल स्क्रिप्ट है:

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

108
2017-10-07 09:54



पूरी तरह से काम किया। बस करना था git reset --hard HEAD^ अन्य स्थानीय भंडारों पर उन्हें दो बार पहले संस्करण में लाने के लिए, git pullसंशोधित संस्करण, और यहां मैं बिना किसी लाइन के हूँ unknown <stupid-windows-user@.StupidWindowsDomain.local> (गिट के डिफ़ॉल्ट को प्यार करने के लिए मिला)। - Alan Plum
मैं इसके बाद धक्का नहीं दे सकता। क्या मुझे "-f" का उपयोग करना है? - fossilet
मैंने किया git push -f। इसके अलावा, इसके बाद स्थानीय प्रतिनिधि को फिर से जाना होगा। - fossilet
यदि आपको किसी विशिष्ट शाखा पर शेल स्क्रिप्ट चलाने की आवश्यकता है तो आप अंतिम पंक्ति को "मास्टर" अपने शाखा-नाम "में बदल सकते हैं (मान लीजिए कि आप मास्टर के ब्रांच किए गए हैं)। - Robert Kajic
लिंक को <अच्छा समाधान> पर क्लिक करें क्योंकि स्क्रिप्ट को अपडेट किया गया है - mdn


जैसा कि डॉक्ग्नोम ने उल्लेख किया है, इतिहास लिखना खतरनाक है और अन्य लोगों के भंडार तोड़ देगा।

लेकिन अगर आप वास्तव में ऐसा करना चाहते हैं और आप एक बाश पर्यावरण में हैं (विंडोज़ पर लिनक्स में कोई समस्या नहीं है, तो आप गिट बैश का उपयोग कर सकते हैं, जो कि गिट की स्थापना के साथ प्रदान किया जाता है), उपयोग गिट फ़िल्टर-शाखा:

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

79
2017-08-04 00:52



ध्यान दें कि यह पुराने कामों पर इंगित किसी भी टैग को छोड़ देगा। --tag-name-filter cat "इसे काम करें" विकल्प है। - Roman Starkov
@romkyns टैग को कैसे बदला जाए इस पर कोई विचार है? - Nick Volynkin
@NickVolynkin हां, आप निर्दिष्ट करते हैं --tag-name-filter cat। यह वास्तव में डिफ़ॉल्ट व्यवहार होना चाहिए था। - Roman Starkov


किसी अन्य लेखक से अनमोल प्रतिबद्धता लेने पर, इसे संभालने का एक आसान तरीका है।

git commit --amend --reset-author


46
2018-03-23 22:23



एक ही प्रतिबद्धता के लिए, और यदि आप अपना उपयोगकर्ता नाम रखना चाहते हैं, तो यह सबसे आसान तरीका है। - Pedro Benevides
आप जोड़ सकते हो --no-edit इसे और भी आसान बनाने के लिए, आम तौर पर अधिकांश लोग केवल ईमेल पता अपडेट करना चाहते हैं, न कि प्रतिबद्ध संदेश - PlagueHammer
क्या आप लोग अंतिम प्रतिबद्धता के ईमेल / उपयोगकर्ता नाम को नए के साथ अपडेट करने के लिए कृपया गिट कमांड साझा कर सकते हैं - adi
क्या आपने यह कोशिश की? अगर ऐसा नहीं है, तो इसका दुष्प्रभाव होना चाहिए stackoverflow.com/a/2717477/654245 एक अच्छा रास्ता की तरह दिखता है। - Ryanmt