बिना कमिट-इन के दो परिवर्तनों के बीच के बदलाव को कैसे देखा जाए?


642

आप git diffकेवल दो कमिट के बीच का अंतर कैसे दिखाते हैं, दूसरे कमिट को बीच में छोड़कर?


15
"गिट डिफरेंस" हमेशा दो कमिट्स (या कमिट और वर्किंग डायरेक्टरी, आदि) के बीच अंतर दिखाता है।
जकुब नारबस्की

21
@ JakubNar Jakbski, वह पूछ रहा है कि एक कमांड द्वारा शुरू किए गए परिवर्तनों और किसी अन्य द्वारा किए गए परिवर्तनों के बीच अंतर कैसे देखें। दूसरे शब्दों में, अंतर या अंतर का अंतर।
Psusi

1
और अगर आप डिफाल्ट = फाइल पैरामीटर को डिफेंड कमांड में जोड़ते हैं, तो आप सटीक प्रोजेक्ट्स और फाइल में बहुत अच्छे स्क्रीनशॉट लेंगे, जो बदले हुए प्रतिशत के साथ बदल रहे हैं। इस तरह: git diff [कमिट-नंबर] [कमिट-नंबर] --डस्टैट = फाइल्स
Ibáñez Fernández

जवाबों:


605

आप बस 2 कमिट्स को पास कर सकते हैं जैसे git diff:

-> git diff 0da94be  59ff30c > my.patch
-> git apply my.patch

1
मेरे लिए यह काम कर गया, लेकिन अब, मैं my.patchदूसरी शाखा में कैसे आवेदन कर सकता हूं ?
nacho4d

2
@ nacho4d: git checkout अन्य-ब्रांच और& git my.patch और& git add लागू करें। && गिट कमिट "मैसेज"
फेलिक्स राबे

1
गिट लागू बनाम पैच का उपयोग करने का लाभ यह है कि आप नाम और कुछ अन्य परिवर्तन शामिल कर सकते हैं जो गिट के लिए विशिष्ट हैं। मुझे git फॉर्मेट-पैच और git am का उपयोग करना पसंद है।
रसेल

58
यह उत्तर प्रश्न को संबोधित करने में पूरी तरह से विफल रहता है, इसलिए मुझे नहीं पता कि इसमें इतने सारे अपवोट क्यों हैं। ओपी विशेष रूप से पूछ रहा है कि आपके द्वारा दी जाने वाली पहली कमांड कैसे नहीं मिल सकती है, और दूसरे का कुछ भी करने के लिए कुछ भी नहीं है।
17

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

142

अंतर के बीच में / दो / कमिट्स के बीच में कमिट्स को शामिल किए बिना पूछना थोड़ा समझ में आता है। कमेटी रिपॉजिटरी की सामग्री के केवल स्नैपशॉट हैं; दो के बीच अंतर के लिए पूछना जरूरी उन्हें शामिल करता है। तो फिर सवाल यह है कि आप वास्तव में क्या देख रहे हैं?

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

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

यह 'एब्सडेफ' लेता है, इसकी तुलना उसके पूर्वज से करता है, फिर उस अंतर को लागू करता है '012345' के शीर्ष पर को । यह नया अंतर तब दिखाया गया है - केवल परिवर्तन '012345' से आता है न कि 'एब्सीडफ के तत्काल पूर्वज से। बेशक, आप संघर्ष और आदि प्राप्त कर सकते हैं, इसलिए यह ज्यादातर मामलों में बहुत उपयोगी प्रक्रिया नहीं है।

यदि आप केवल abcdef में ही रुचि रखते हैं, तो आप कर सकते हैं:

$ git log -u -1 abcdef

यह abcdef की तुलना उसके तत्काल पूर्वज, अकेले और आमतौर पर वही करता है जो आप चाहते हैं।

और निश्चित रूप से

$ git diff 012345..abcdef

आपको उन दो आवागमन के बीच सभी अंतर देता है।

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


41
मैं सहमत हूँ कि, सामान्य तौर पर, दो कमिट्स की तुलना करने का कोई मतलब नहीं है। लेकिन गिट वास्तव में आपको यह नहीं बताने के लिए अच्छा है कि आपको कैसे सोचना चाहिए। मान लें कि आपकी दो शाखाएँ हैं, जिनमें से प्रत्येक के पास अलग-अलग कमिट्स हैं, जो इस तरह दिखते हैं जैसे वे फ़ाइलों के समान सेट में समान परिवर्तन कर रहे हैं। मैं यह बताने में सक्षम होना चाहूंगा कि क्या ये दोनों पैच मेरी आंखों पर भरोसा किए बिना समान हैं। मुझे लगता है कि इसमें आईएस की उपयोगिता है।
क्रिस क्लेलैंड

9
@ क्रिसललैंड, उस मामले में इंटरडिफ़ की उपयोगिता काम आ सकती है। अपने तत्काल माता-पिता के खिलाफ प्रत्येक कमिट का फ़र्क पाने के लिए git भिन्न का उपयोग करें, फिर अंतर की तुलना करने के लिए इंटरडिफ़ का उपयोग करें।
bdonlan

3
@ क्रिसक्लैंड, git पैच को स्टोर नहीं करता है। यह फ़ाइल सामग्री संग्रहीत करता है। इसमें एक संपीड़न योजना होती है जो डेल्टा का उपयोग करती है, लेकिन डेल्टा स्रोत आवश्यक रूप से फाइलों के वास्तविक इतिहास के साथ संबंधित नहीं हैं।
bdonlan

11
अपनी-अपनी शाखाओं पर अन्य कमिट्स को छोड़कर दोनों के बीच का अंतर सही मायने में सही है: एक कमिट दूसरे से लिया गया चेरी था, लेकिन इसमें कुछ सूक्ष्म अंतर हो सकते हैं। आप यह देखना चाहते हैं कि दोनों शाखाओं के बीच अलग-अलग अन्य सभी असंबंधित बकवासों के बिना वे क्या बरबाद हो रहे हैं।
17

2
या यूं कहें कि आप एक सुविधा शाखा में मास्टर को रिबेट करते हैं, और संघर्षों को हल करना चाहिए। बाद में तुलना origin/featurebranch#HEADकरने local/featurebranch#HEADसे आपको यह सुनिश्चित करने में मदद मिल सकती है कि आपने संघर्ष-समाधान के दौरान कुछ भी नहीं किया है।
लेफनिरे

91

दो git की तुलना 12345 और abcdef से करता है जैसे पैच एक के रूप में अलग कमांड का उपयोग कर सकता है

diff <(git show 123456) <(git show abcdef)

8
आप GNU का उपयोग गिट के साथ क्यों करेंगे?
OneOfOne

7
@OneOfOne git diff <(git show 123456) <(git show abcdef)काम नहीं करता है; diff <(...) <(...)कर देता है। (मैंने अभी कोशिश की)।
मेनकेम

@ मेनकेम git diff 123456 abcdef
वनऑफने

15
@OneOfOne यही काम नहीं करता है। आपने जो सुझाव दिया है , वह एक पैच दिखाते हुए, प्रत्येक प्रतिबद्ध के पेड़ों की तुलना करेगा । मैं (और @plexoos) जो कर रहे हैं दो पैच की तुलना कर रहे हैं , प्रत्येक को अलग-अलग कमिट द्वारा पेश किया गया है - दूसरे शब्दों में, दो एस से आउटपुट को निगलना । इसमें दो इनपुट स्ट्रीम पढ़ना और तुलना करना शामिल है। (जीएनयू, या यूनिक्स ) , ऐसा नहीं कर सकता। कुछ लोग सोच सकते हैं कि कोई ऐसा क्यों करना चाहेगा। मैं अभी उस काम को करने के बीच में हूं, जो एक मर्ज को साफ कर रहा है जो खराब हो गया है। diffdiffdiffdiffgit diff
मेनकेम

1
क्या इसमें git के सभी मेटाडेटा के gn अंतर शामिल नहीं होंगे?
जोएलब

61
git diff <a-commit> <another-commit> path

उदाहरण:

git diff commit1 commit2 config/routes.rb

यह उन कमिट्स के बीच उस फाइल के अंतर को दिखाता है।


24

पूर्ण परिवर्तनों की जाँच के लिए:

  git diff <commit_Id_1> <commit_Id_2>

केवल परिवर्तित / जोड़े / हटाए गए फ़ाइलों की जाँच के लिए:

  git diff <commit_Id_1> <commit_Id_2> --name-only

नोट : जाँच के लिए बीच में कमिट के बिना, आपको कमिट आईडी डालने की आवश्यकता नहीं है।


20

मान लीजिए कि आपके पास यह है

A
|
B    A0
|    |
C    D
\   /
  |
 ...

और आप यह सुनिश्चित करना चाहते हैं कि Aजैसा है वैसा ही हो A0

यह चाल चलेगा:

$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff

3
केवल @plexoos द्वारा उत्तर के रूप में एक-लाइनर के रूप में छोटा किया जा सकता है : diff <(git diff B A) <(git diff D A0)(गिट शो के साथ एक ही परिणाम)
पोगोस्मा

14

मान लीजिए आप 012345 और abcdef के बीच अंतर देखना चाहते हैं। निम्नलिखित को वह करना चाहिए जो आप चाहते हैं:

$ git चेकआउट 012345
$ git चेरी-पिक-एन abcdef
$ गिट अंतर - कैश किया गया

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

10

इस बारे में क्या:

git diff abcdef 123456 | less

यदि आप मक्खी पर कई अलग-अलग रूपों की तुलना करना चाहते हैं तो इसे कम से कम पाइप करना आसान है।


6

Git 2.19 के बाद से, आप बस उपयोग कर सकते हैं:

git range-diff rev1...rev2 - दो प्रतिबद्ध पेड़ों की तुलना करें, उनके सामान्य पूर्वज द्वारा शुरू

या git range-diff rev1~..rev1 rev2~..rev2 - दिए गए परिवर्तनों की तुलना 2 दिए गए कमिट द्वारा की जाती है


4

फ़ाइल aliasमें मेरी सेटिंग :~/.bashrcgit diff

alias gdca='git diff --cached' # diff between your staged file and the last commit
alias gdcc='git diff HEAD{,^}' # diff between your latest two commits

2

फ़ाइल aliasमें मेरी सेटिंग :~/.zshrcgit diff

alias gdf='git diff HEAD{'^',}' # diff between your recent tow commits

साभार @Jinmiao लुओ


git diff HEAD~2 HEAD

नवीनतम 2 वें प्रतिबद्ध और वर्तमान के बीच पूर्ण परिवर्तन।

HEAD सुविधाजनक है


1

मैंने एक स्क्रिप्ट लिखी जो दो कमिट के बीच प्रदर्शित होती है, उबंटू पर अच्छी तरह से काम करती है।

https://gist.github.com/jacobabrahamb4/a60624d6274ece7a0bd2d141b53407bc

#!/usr/bin/env python
import sys, subprocess, os

TOOLS = ['bcompare', 'meld']

def getTool():
    for tool in TOOLS:
        try:
            out = subprocess.check_output(['which', tool]).strip()
            if tool in out:
                return tool
        except subprocess.CalledProcessError:
            pass
    return None

def printUsageAndExit():
    print 'Usage: python bdiff.py <project> <commit_one> <commit_two>'
    print 'Example: python bdiff.py <project> 0 1'
    print 'Example: python bdiff.py <project> fhejk7fe d78ewg9we'
    print 'Example: python bdiff.py <project> 0 d78ewg9we'
    sys.exit(0)

def getCommitIds(name, first, second):
    commit1 = None
    commit2 = None
    try:
        first_index = int(first) - 1
        second_index = int(second) - 1
        if int(first) < 0 or int(second) < 0:
            print "Cannot handle negative values: "
            sys.exit(0)
        logs = subprocess.check_output(['git', '-C', name, 'log', '--oneline', '--reverse']).split('\n')
        if first_index >= 0:
            commit1 = logs[first_index].split(' ')[0]
        if second_index >= 0:
            commit2 = logs[second_index].split(' ')[0]
    except ValueError:
        if first != '0':
            commit1 = first
        if second != '0':
            commit2 = second
    return commit1, commit2

def validateCommitIds(name, commit1, commit2):
    if commit1 == None and commit2 == None:
        print "Nothing to do, exit!"
        return False
    try:
        if commit1 != None:
            subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit1]).strip()
        if commit2 != None:
            subprocess.check_output(['git', '-C', name, 'cat-file', '-t', commit2]).strip()
    except subprocess.CalledProcessError:
        return False
    return True

def cleanup(commit1, commit2):
        subprocess.check_output(['rm', '-rf', '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])

def checkoutCommit(name, commit):
    if commit != None:
        subprocess.check_output(['git', 'clone', name, '/tmp/'+commit])
        subprocess.check_output(['git', '-C', '/tmp/'+commit, 'checkout', commit])
    else:
        subprocess.check_output(['mkdir', '/tmp/0'])

def compare(tool, commit1, commit2):
        subprocess.check_output([tool, '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])

if __name__=='__main__':
    tool = getTool()
    if tool == None:
        print "No GUI diff tools"
        sys.exit(0)
    if len(sys.argv) != 4:
        printUsageAndExit()

    name, first, second = None, 0, 0
    try:
        name, first, second = sys.argv[1], sys.argv[2], sys.argv[3]
    except IndexError:
        printUsageAndExit()

    commit1, commit2 = getCommitIds(name, first, second)

    if not validateCommitIds(name, commit1, commit2):
        sys.exit(0)

    cleanup(commit1, commit2)
    checkoutCommit(name, commit1)
    checkoutCommit(name, commit2)

    try:
        compare(tool, commit1, commit2)
    except KeyboardInterrupt:
        pass
    finally:
        cleanup(commit1, commit2)
    sys.exit(0)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.