Git में रूट कमिट करने से पहले एक कमिट डालें?


231

मैंने पहले पूछा है कि पहले दो हिट्स को एक रिपॉजिटरी में कैसे स्क्वैश किया जाए

जबकि समाधान दिलचस्प नहीं हैं और वास्तव में मन-युद्ध के रूप में कुछ अन्य चीजों के रूप में नहीं हैं, वे अभी भी चोट के लौकिक बैग के एक बिट हैं यदि आपको अपनी परियोजना के विकास के साथ कई बार प्रक्रिया को दोहराने की आवश्यकता होती है।

इसलिए, मैं केवल एक बार दर्द से गुजरना चाहता हूं, और फिर हमेशा मानक इंटरएक्टिव छूट का उपयोग करने में सक्षम हो सकता हूं।

फिर मैं जो करना चाहता हूं, वह एक प्रारंभिक प्रारंभिक प्रतिबद्धता है जो पूरी तरह से पहले होने के उद्देश्य से मौजूद है। कोई कोड नहीं, कुछ भी नहीं। बस जगह ले रहा है तो यह रिबेस के लिए आधार हो सकता है।

मेरा सवाल यह है कि मौजूदा रिपॉजिटरी होने के नाते, मैं पहले वाले से पहले एक नई, खाली कमेटी कैसे डालूं और बाकी सभी को आगे बढ़ाऊं?


3
;) मुझे लगता है कि यह वैसे भी एक उत्तर का वारंट करता है। मैं कई तरीकों की खोज करने के लिए तैयार हूं, जो इतिहास के संपादन द्वारा पागल हो सकते हैं। चिंता न करें, साझा भंडार नहीं।
kch

11
एक जुनूनी, पागल इतिहास संपादक से दूसरे तक, सवाल पोस्ट करने के लिए धन्यवाद! ; डी
मार्को

10
@ Kch के बचाव में, एक पूरी तरह से वैध कारण यह है कि मैं खुद को इसमें पाती हूं: एक ऐतिहासिक संस्करण का स्नैपशॉट जोड़ना जो रेपो में कभी भी कब्जा नहीं किया गया था।
बजे ओल्ड मैकसोफर जूल

4
मेरे पास एक और वैध कारण है! पहले से पहले खाली करने और बाइनरी ब्लोट को हटाने के लिए सक्षम करने के लिए पहले से पहले एक खाली प्रतिबद्ध जोड़ना एक रिपॉजिटरी की प्रारंभिक प्रतिबद्ध में जोड़ा गया: (
पोस्पाई

जवाबों:


314

इसे प्राप्त करने के लिए 2 चरण हैं:

  1. एक नई खाली प्रतिबद्ध बनाएँ
  2. इस खाली प्रतिबद्ध से शुरू करने के लिए इतिहास को फिर से लिखना

हम नई खाली प्रतिबद्ध newrootसुविधा के लिए एक अस्थायी शाखा पर रख देंगे ।

1. एक नई खाली प्रतिबद्ध बनाएँ

ऐसा करने के कई तरीके हैं।

सिर्फ नलसाजी का उपयोग करना

सबसे साफ तरीका यह है कि Git की प्लंबिंग का उपयोग सीधे एक कमिट बनाने के लिए किया जाए, जो कि वर्किंग कॉपी या इंडेक्स को छूने से बचता है या किस ब्रांच को चेक किया जाता है, आदि।

  1. खाली निर्देशिका के लिए ट्री ऑब्जेक्ट बनाएं:

    tree=`git hash-object -wt tree --stdin < /dev/null`
    
  2. इसके चारों ओर एक आवरण लपेटें:

    commit=`git commit-tree -m 'root commit' $tree`
    
  3. इसके लिए एक संदर्भ बनाएँ:

    git branch newroot $commit
    

यदि आप अपने शेल को अच्छी तरह से जानते हैं तो आप पूरी प्रक्रिया को एक-लाइनर में बदल सकते हैं।

बिना प्लंबिंग के

नियमित रूप से चीनी मिट्टी के बरतन आदेशों के साथ, आप बिना newrootकिसी अच्छे कारण के, शाखा की जाँच और सूचकांक को अद्यतन करने और बार-बार कॉपी करने के बिना एक खाली प्रतिबद्ध नहीं बना सकते हैं । लेकिन कुछ को समझने में यह आसान लग सकता है:

git checkout --orphan newroot
git rm -rf .
git clean -fd
git commit --allow-empty -m 'root commit'

ध्यान दें कि Git के बहुत पुराने संस्करणों पर --orphanस्विच की कमी है checkout, आपको इसके साथ पहली पंक्ति को बदलना होगा:

git symbolic-ref HEAD refs/heads/newroot

2. इस खाली प्रतिबद्ध से शुरू करने के लिए इतिहास को फिर से लिखना

आपके पास यहां दो विकल्प हैं: रिबासिंग, या एक स्वच्छ इतिहास फिर से लिखना।

रिबेसिंग

git rebase --onto newroot --root master

इसमें सादगी का गुण है। हालांकि, यह शाखा पर हर अंतिम प्रतिबद्ध पर कमिट नाम और तारीख को भी अपडेट करेगा।

इसके अलावा, कुछ एज केस हिस्ट्री के साथ, यह मर्ज संघर्ष के कारण भी विफल हो सकता है - इस तथ्य के बावजूद कि आप एक ऐसी प्रतिबद्धता पर रिबास कर रहे हैं जिसमें कुछ भी नहीं है।

इतिहास फिर से लिखना

क्लीनर दृष्टिकोण शाखा को फिर से लिखना है। इसके विपरीत git rebase, आपको यह देखना होगा कि आपकी शाखा किस से शुरू होती है:

git replace <currentroot> --graft newroot
git filter-branch master

पुनर्लेखन दूसरे चरण में होता है, जाहिर है; यह पहला कदम है जिसे स्पष्टीकरण की आवश्यकता है। यह क्या git replaceबताता है कि Git बताता है कि जब भी वह किसी ऑब्जेक्ट का संदर्भ देखता है जिसे आप प्रतिस्थापित करना चाहते हैं, तो Git को उस ऑब्जेक्ट के प्रतिस्थापन को देखना चाहिए।

--graftस्विच के साथ , आप इसे सामान्य से थोड़ा अलग बता रहे हैं। आप कह रहे हैं कि आपके पास अभी तक एक प्रतिस्थापन वस्तु नहीं है, लेकिन आप चाहते हैं कि <currentroot>वस्तु वस्तु को स्वयं की एक सटीक प्रति के साथ प्रतिस्थापित किया जाए, सिवाय इसके कि प्रतिस्थापन के माता-पिता के प्रतिबद्ध (ओं) को आप सूचीबद्ध करें (यानी newrootप्रतिबद्ध) )। फिर git replaceआगे बढ़ता है और आपके लिए यह प्रतिबद्ध बनाता है, और फिर घोषणा करता है कि आपकी मूल प्रतिबद्ध के लिए यह प्रतिस्थापन है।

अब यदि आप एक करते हैं git log, तो आप देखेंगे कि चीजें पहले से ही दिख रही हैं जैसा कि आप उन्हें चाहते हैं: शाखा से शुरू होता है newroot

हालांकि, ध्यान दें कि git replace वास्तव में इतिहास को संशोधित नहीं करता है - और न ही यह आपके भंडार से बाहर प्रचारित करता है। यह केवल एक वस्तु से दूसरी वस्तु में आपके भंडार में एक स्थानीय पुनर्निर्देशन जोड़ता है। इसका मतलब यह है कि कोई और इस प्रतिस्थापन के प्रभाव को नहीं देखता है - केवल आप।

इसलिए filter-branchकदम जरूरी है। साथ git replaceआप रूट के लिए समायोजित माता पिता प्रतिबद्ध के साथ एक सटीक प्रतिलिपि बनाने के लिए प्रतिबद्ध; git filter-branchफिर इस प्रक्रिया को निम्नलिखित सभी कमिटों के लिए भी दोहराता है। यही वह जगह है जहां इतिहास वास्तव में फिर से लिखा जाता है ताकि आप इसे साझा कर सकें।


1
वह --onto newrootविकल्प बेमानी है; आप इसके बिना कर सकते हैं क्योंकि आप जिस तर्क से इसे पारित करते हैं, newrootवह अपस्ट्रीम तर्क के समान है - newroot
विल्हेमटेल

7
प्लंबिंग कमांड्स के बजाय पोर्सिलेन का उपयोग क्यों नहीं करते? मैं गिट प्रतीकात्मक-रेफरी HEAD रेफरी / सिर / न्यूट्रोट को गिट चेकआउट के
बोरहान

4
@nenopera: क्योंकि यह उत्तर git-checkoutउस स्विच के पहले लिखा गया था । मैंने इसे अद्यतन करने के लिए कहा है कि पहले दृष्टिकोण, सूचक के लिए धन्यवाद।
अरस्तू पगलतज़िस

1
यदि आपका न्यूट्रोट खाली नहीं है, तो git rebase --merge -s recursive -X theirs --onto newroot --root masterसभी विरोधों को स्वचालित रूप से हल करने के लिए उपयोग करें ( यह उत्तर देखें )। @AlexanderKuzin
उपयोगकर्ता

1
@Geremia आप केवल अंतिम प्रतिबद्ध में संशोधन कर सकते हैं, इसलिए यदि आपकी रिपॉजिटरी में केवल रूट कमिट है, तो यह काम कर सकता है, अन्यथा आपको वैसे भी संशोधित रूट कमेटी के शीर्ष पर रेपो में अन्य सभी कमिट्स को फिर से भरना होगा। लेकिन फिर भी, विषय का अर्थ है कि आप रूट कमिट को बदलना नहीं चाहते हैं, लेकिन मौजूदा रूट से पहले एक और डालना चाहते हैं।
उपयोगकर्ता

30

अरस्तू पगाल्ट्ज़िस और उवे क्लेन-कोनिग के उत्तरों और रिचर्ड ब्रोंस्की की टिप्पणी के मर्ज।

git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d
# touch .gitignore && git add .gitignore # if necessary
git commit --allow-empty -m 'initial'
git rebase --onto newroot --root master
git branch -d newroot

(बस सब कुछ एक ही स्थान पर रखने के लिए)


यह उत्कृष्ट है। यह अच्छा होगा अगर यह एक git rebase -i --root आंतरिक रूप से क्या कर सकता है।
एरेड्रिडेल

हां, मुझे यह जानकर आश्चर्य हुआ कि यह नहीं है।
एंटनी हैचकिंस

मुझे git rebase newroot masterत्रुटि के कारण रीबेस कमांड को बदलना पड़ा ।
मारबेल 82

@ इसके लिए एंटनी-हैचकिंस धन्यवाद। मेरे पास एक मौजूदा git रेपो है और (विभिन्न कारणों से जो मैं यहां नहीं जाना चाहता) मैं अपनी पहली प्रतिबद्ध के रूप में एक गैर- EMPTY git कमिट को जोड़ने की कोशिश कर रहा हूं। इसलिए मैंने गिट ऐड के साथ जीआईटी कमिट - क्लो-खाली-एम 'प्रारंभिक' को बदल दिया; जीआईटी कमिट-एम "प्रारंभिक लार्वा कमेट"; जोर धक्का; और फिर यह रिबेस चरण: git rebase - Santiago newroot --root मास्टर टोंन ऑफ मर्ज टकराव के साथ विफल हो रहा है। कोई सलाह? : (
kp123

@ kp123 एक खाली प्रतिबद्ध की कोशिश करें :)
एंटनी हैचकिंस

12

मुझे अरस्तू का जवाब पसंद है। लेकिन पाया गया कि एक बड़ी रिपॉजिटरी (> 5000 कमिट्स) के लिए फ़िल्टर-ब्रांच कई कारणों से रिबेस से बेहतर काम करता है 1) यह तेजी से 2 है) इसमें मर्ज होने पर मानव हस्तक्षेप की आवश्यकता नहीं है। 3) यह टैग को फिर से लिख सकता है - उन्हें संरक्षित करना। ध्यान दें कि फ़िल्टर-शाखा काम करती है क्योंकि प्रत्येक प्रतिबद्ध की सामग्री के बारे में कोई सवाल नहीं है - यह ठीक उसी तरह है जैसे कि इस 'रिबेस' से पहले।

मेरे कदम हैं:

# first you need a new empty branch; let's call it `newroot`
git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d

# then you apply the same steps
git commit --allow-empty -m 'root commit'

# then use filter-branch to rebase everything on newroot
git filter-branch --parent-filter 'sed "s/^\$/-p <sha of newroot>/"' --tag-name-filter cat master

ध्यान दें कि '--tag-name-filter cat' विकल्पों का अर्थ है कि टैग नए बनाए गए कमिट्स को इंगित करने के लिए फिर से लिखे जाएंगे।


यह गैर-रिक्त आवागमन बनाने में मदद नहीं करता है जो एक दिलचस्प उपयोग मामला भी है।
सेप्टिकोको

अन्य समाधानों की तुलना में, आपके पास केवल एक महत्वहीन दुष्प्रभाव है: यह हैश को बदल देता है, लेकिन पूरा इतिहास अछूता रहता है। धन्यवाद!
व्लादिस्लाव सवैंको

5

मैंने अरस्तू और केंट के उत्तर के टुकड़ों का सफलतापूर्वक उपयोग किया:

# first you need a new empty branch; let's call it `newroot`
git checkout --orphan newroot
git rm -rf .
git commit --allow-empty -m 'root commit'
git filter-branch --parent-filter \
'sed "s/^\$/-p <sha of newroot>/"' --tag-name-filter cat -- --all
# clean up
git checkout master
git branch -D newroot
# make sure your branches are OK first before this...
git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

यह masterटैग के अलावा सभी शाखाओं (सिर्फ नहीं ) को भी फिर से लिखेगा।


यह अंतिम पंक्ति क्या करती है?
डिडरिक सी। नेहॉस्टर

यह refs/original/प्रत्येक रेफ को खोजता है और हटाता है। रेफरी जो इसे हटाता है उसे पहले से ही किसी अन्य शाखा द्वारा संदर्भित किया जाना चाहिए, इसलिए वे वास्तव में दूर नहीं जाते हैं, बस refs/original/हटा दिए जाते हैं।
ldav1s

इसने मेरे लिए काम किया। साथ ही मैं इस्तेमाल किया timedatectl set-time '2017-01-01 00:00:00'देने के लिए newrootएक पुराने टाइमस्टैम्प।
17'17

4

git rebase --root --onto $emptyrootcommit

आसानी से चाल करना चाहिए


3
$emptyrootcommitएक शेल वैरिएबल है जो कुछ भी नहीं, निश्चित रूप से फैलता है?
फ्लिक

@ फ़ीलम: $ रिबेरोटोकॉमिट एक खाली कमिट का शै 1 है जो मूल पोस्टर पहले से ही लगता है।
उवे क्लेन-कोनिग

4

मुझे लगता है कि उपयोग करना git replaceऔर git filter-branchउपयोग करने से बेहतर समाधान है git rebase:

  • बेहतर प्रदर्शन
  • आसान और कम जोखिम भरा (आप प्रत्येक चरण में अपना परिणाम सत्यापित कर सकते हैं और आपने जो किया था उसे पूर्ववत करें ...)
  • गारंटीकृत परिणामों के साथ कई शाखाओं के साथ अच्छी तरह से काम करें

इसके पीछे का विचार यह है:

  • अतीत में दूर एक नई खाली प्रतिबद्ध बनाएँ
  • पुरानी रूट कमेटी को कमिट के समान बदलें, सिवाय इसके कि नई रूट कमेटी को माता-पिता के रूप में जोड़ा जाता है
  • सत्यापित करें कि सभी अपेक्षा के अनुरूप हैं और चलते हैं git filter-branch
  • एक बार फिर, सत्यापित करें कि सभी ठीक है और बिना अधिक आवश्यक फ़ाइलों की सफाई करें

यहाँ 2 पहले चरणों के लिए एक स्क्रिप्ट है:

#!/bin/bash
root_commit_sha=$(git rev-list --max-parents=0 HEAD)
git checkout --force --orphan new-root
find . -path ./.git -prune -o -exec rm -rf {} \; 2> /dev/null
git add -A
GIT_COMMITTER_DATE="2000-01-01T12:00:00" git commit --date==2000-01-01T12:00:00 --allow-empty -m "empty root commit"
new_root_commit_sha=$(git rev-parse HEAD)

echo "The commit '$new_root_commit_sha' will be added before existing root commit '$root_commit_sha'..."

parent="parent $new_root_commit_sha"
replacement_commit=$(
 git cat-file commit $root_commit_sha | sed "s/author/$parent\nauthor/" |
 git hash-object -t commit -w --stdin
) || return 3
git replace "$root_commit_sha" "$replacement_commit"

आप जोखिम के बिना इस स्क्रिप्ट को चला सकते हैं (भले ही कार्रवाई करने से पहले बैकअप लेना कभी भी अच्छा विचार नहीं है;)), और यदि परिणाम अपेक्षित नहीं है, तो बस फ़ोल्डर में बनाई गई फ़ाइलों को हटा दें .git/refs/replaceऔर फिर से प्रयास करें; )

एक बार जब आप सत्यापित कर लेते हैं कि रिपॉजिटरी की स्थिति वही है जो आप उम्मीद करते हैं, तो सभी शाखाओं के इतिहास को अपडेट करने के लिए निम्न कमांड चलाएँ :

git filter-branch -- --all

अब, आपको 2 इतिहास, पुराना एक और नया देखना होगा ( filter-branchअधिक जानकारी के लिए सहायता देखें)। आप 2 की तुलना कर सकते हैं और फिर से जांच सकते हैं कि सब ठीक है या नहीं। यदि आप संतुष्ट हैं, तो अधिक आवश्यक फ़ाइलों को न हटाएं:

rm -rf ./.git/refs/original
rm -rf ./.git/refs/replace

आप अपनी masterशाखा में लौट सकते हैं और अस्थायी शाखा को हटा सकते हैं :

git checkout master
git branch -D new-root

अब, सब किया जाना चाहिए;)


3

मैं उत्साहित हो गया और इस अच्छी स्क्रिप्ट का एक 'idempotent' संस्करण लिखा ... यह हमेशा एक ही खाली प्रतिबद्ध सम्मिलित करेगा, और यदि आप इसे दो बार चलाते हैं, तो यह आपके प्रतिबद्ध हैश को हर बार नहीं बदलता है। तो, यहाँ मेरा गिट-इंसर्ट-खाली-रूट है :

#!/bin/sh -ev
# idempotence achieved!
tmp_branch=__tmp_empty_root
git symbolic-ref HEAD refs/heads/$tmp_branch
git rm --cached -r . || true
git clean -f -d
touch -d '1970-01-01 UTC' .
GIT_COMMITTER_DATE='1970-01-01T00:00:00 +0000' git commit \
  --date='1970-01-01T00:00:00 +0000' --allow-empty -m 'initial'
git rebase --committer-date-is-author-date --onto $tmp_branch --root master
git branch -d $tmp_branch

क्या यह अतिरिक्त जटिलता के लायक है? शायद नहीं, लेकिन मैं इसे इस्तेमाल करूंगा।

यह SHOULD रेपो की कई क्लोन प्रतियों पर भी इस ऑपरेशन को करने की अनुमति देता है, और एक ही परिणाम के साथ समाप्त होता है, इसलिए वे अभी भी संगत हैं ... परीक्षण ... हाँ यह काम करता है, लेकिन हटाने और अपने को जोड़ने के लिए भी आवश्यक है फिर से बताता है, उदाहरण के लिए:

git remote rm origin
git remote add --track master user@host:path/to/repo

3

एक रिपॉजिटरी की शुरुआत में एक खाली प्रतिबद्ध जोड़ने के लिए, यदि आप "इनिट" के तुरंत बाद एक खाली प्रतिबद्ध बनाना भूल गए:

git rebase --root --onto $(git commit-tree -m 'Initial commit (empty)' 4b825dc642cb6eb9a060e54bf8d69288fbee4904)

1
: 4b825dc ... खाली पेड़ के हैश है stackoverflow.com/questions/9765453/...
mrks

2

खैर, यहाँ मैं क्या लेकर आया हूँ:

# Just setting variables on top for clarity.
# Set this to the path to your original repository.
ORIGINAL_REPO=/path/to/original/repository

# Create a new repository…
mkdir fun
cd fun
git init
# …and add an initial empty commit to it
git commit --allow-empty -m "The first evil."

# Add the original repository as a remote
git remote add previous $ORIGINAL_REPO
git fetch previous

# Get the hash for the first commit in the original repository
FIRST=`git log previous/master --pretty=format:%H  --reverse | head -1`
# Cherry-pick it
git cherry-pick $FIRST
# Then rebase the remainder of the original branch on top of the newly 
# cherry-picked, previously first commit, which is happily the second 
# on this branch, right after the empty one.
git rebase --onto master master previous/master

# rebase --onto leaves your head detached, I don't really know why)
# So now you overwrite your master branch with the newly rebased tree.
# You're now kinda done.
git branch -f master
git checkout master
# But do clean up: remove the remote, you don't need it anymore
git remote rm previous

2

यहाँ मेरी bashस्क्रिप्ट में सुधार के साथ केंट के उत्तर पर आधारित है :

  • यह मूल शाखा की जाँच करता है, न कि masterजब किया जाता है;
  • मैंने अस्थायी शाखा से बचने की कोशिश की, लेकिन git checkout --orphanकेवल एक शाखा के साथ काम करता है, अलग-अलग राज्य नहीं, इसलिए नई रूट कमिट करने और फिर हटाए जाने के लिए इसे लंबे समय तक चेक किया जाता है;
  • यह नए रूट कमिट के हैश का उपयोग करता है filter-branch(केंट ने मैन्युअल प्रतिस्थापन के लिए एक प्लेसहोल्डर को वहां छोड़ दिया);
  • filter-branchआपरेशन केवल स्थानीय शाखाओं पुनर्लेखन करता है, भी नहीं remotes
  • लेखक और कमिटर मेटाडेटा को मानकीकृत किया गया है ताकि रूट कमेटी रिपॉजिटरी में समान हो।

#!/bin/bash

# Save the current branch so we can check it out again later
INITIAL_BRANCH=`git symbolic-ref --short HEAD`
TEMP_BRANCH='newroot'

# Create a new temporary branch at a new root, and remove everything from the tree
git checkout --orphan "$TEMP_BRANCH"
git rm -rf .

# Commit this empty state with generic metadata that will not change - this should result in the same commit hash every time
export GIT_AUTHOR_NAME='nobody'
export GIT_AUTHOR_EMAIL='nobody@example.org'
export GIT_AUTHOR_DATE='2000-01-01T00:00:00+0000'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git commit --allow-empty -m 'empty root'
NEWROOT=`git rev-parse HEAD`

# Check out the commit we just made and delete the temporary branch
git checkout --detach "$NEWROOT"
git branch -D "$TEMP_BRANCH"

# Rewrite all the local branches to insert the new root commit, delete the 
# original/* branches left behind, and check out the rewritten initial branch
git filter-branch --parent-filter "sed \"s/^\$/-p $NEWROOT/\"" --tag-name-filter cat -- --branches
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git checkout "$INITIAL_BRANCH"

2

रूट कमिट स्विच करने के लिए:

सबसे पहले, पहले जैसा कमिटमेंट बनाएं।

दूसरा, उपयोग करने वाले कमिट के क्रम को स्विच करें:

git rebase -i --root

जब तक रूट कमिट नहीं होगा तब तक एक एडिटर कमिटर्स के साथ दिखाई देगा:

1234 पुराना रूट संदेश चुनें

बीच में 0294 A कमिट करें

5678 चुनें जो आप रूट पर रखना चाहते हैं

इसके बाद आप पहली बार मनचाहा वचन दे सकते हैं, इसे पहली पंक्ति में रखकर। उदाहरण में:

5678 चुनें जो आप रूट पर रखना चाहते हैं

1234 पुराना रूट संदेश चुनें

बीच में 0294 A कमिट करें

संपादक से बाहर निकलें प्रतिबद्ध आदेश बदल गया है।

पुनश्च: संपादक का उपयोग करने के लिए परिवर्तन का उपयोग करें, भागो:

git config --global core.editor name_of_the_editor_program_you_want_to_use


1
अब उस रिबास में --root है, यह अब तक का सबसे साफ समाधान है।
रॉस बर्टन

1

नवीनतम और महानतम का मेल। टैग रखने पर कोई साइड इफेक्ट नहीं, कोई विरोध नहीं।

git log --reverse

tree=`git hash-object -wt tree --stdin < /dev/null`
commit=`git commit-tree -m 'Initialize empty repository' $tree`
echo $commit # copy below, interpolation didn't work for me

git filter-branch --parent-filter 'sed "s/^\$/-p <commit>/"' --tag-name-filter cat master

git log --reverse

ध्यान दें कि GitHub पर आप CI रन डेटा खो देंगे और PR तब तक गड़बड़ हो सकता है जब तक कि अन्य शाखाएं भी तय नहीं होती हैं।


0

उत्तर अरस्तू पगलतज़िस और अन्य के बाद लेकिन अधिक सरल आदेशों का उपयोग करते हुए

zsh% git checkout --orphan empty     
Switched to a new branch 'empty'
zsh% git rm --cached -r .
zsh% git clean -fdx
zsh% git commit --allow-empty -m 'initial empty commit'
[empty (root-commit) 64ea894] initial empty commit
zsh% git checkout master
Switched to branch 'master'
zsh% git rebase empty
First, rewinding head to replay your work on top of it...
zsh% git branch -d empty 
Deleted branch empty (was 64ea894).

ध्यान दें कि आपके रेपो में कोई स्थानीय संशोधन नहीं होना चाहिए जिसका इंतजार किया जाए।
नोट git checkout --orphangit के नए संस्करणों पर काम करेगा, मुझे लगता है।
नोट ज्यादातर समय git statusउपयोगी संकेत देता है।


-6

एक नया भंडार शुरू करें।

अपनी तिथि को अपनी इच्छित तिथि पर वापस सेट करें।

जिस तरह से आप यह करना चाहते हैं वह सब कुछ करें, सिस्टम समय को प्रतिबिंबित करने के लिए समायोजित करना जब आप चाहें तो आप इसे इस तरह से करेंगे। मौजूदा रिपॉजिटरी से फ़ाइलों को खींचो, क्योंकि बहुत से अनावश्यक टाइपिंग से बचने के लिए।

जब आप आज के लिए जाते हैं, तो रिपॉजिटरी को स्वैप करें और आपका काम हो गया।

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

इससे यह भी अच्छा होगा जब आप तय करेंगे कि आप चाहते हैं कि अतीत अब से एक हफ्ते बाद किसी और तरह से हुआ हो।


मेरे पास एक समाधान के बारे में बुरी भावनाएं हैं जिनके लिए आपको सिस्टम की तारीख के साथ गड़बड़ करने की आवश्यकता है, लेकिन आपने मुझे एक विचार दिया, जिसे मैंने थोड़ा विकसित किया और अफसोस, यह काम किया। तो धन्यवाद।
kch

-7

मुझे पता है कि यह पोस्ट पुरानी है लेकिन यह पेज पहला है जब Googling "इन्सर्टिंग कमिट"।

सरल चीजों को जटिल क्यों बनाते हैं?

आपके पास एबीसी है और आप एबीजेडसी चाहते हैं।

  1. git rebase -i trunk (या बी से पहले कुछ भी)
  2. बी लाइन पर संपादित करने के लिए परिवर्तन चुनें
  3. अपने परिवर्तन करें: git add ..
  4. git commit( git commit --amendजो B को संपादित करेगा और Z नहीं बनाएगा)

[आप git commitज्यादा से ज्यादा कमिट्स डालने के लिए जितने चाहें उतने बना सकते हैं । बेशक, आपको चरण 5 के साथ परेशानी हो सकती है, लेकिन गिट के साथ विलय के संघर्ष को हल करना एक कौशल है जो आपके पास होना चाहिए। यदि नहीं, तो अभ्यास करें!]

  1. git rebase --continue

सरल, है ना?

यदि आप समझते हैं git rebase, तो 'रूट' कमिट जोड़ने से कोई समस्या नहीं होनी चाहिए।

मस्ती से मजा लो!


5
पहला कमिट डालने के लिए सवाल पूछता है : एबीसी से आप जेडएबीसी चाहते हैं। एक सीधा git rebaseऐसा नहीं कर सकता।
पेट्र विक्टोरिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.