একটি নির্দিষ্ট প্রতিশ্রুতি অন্তর্ভুক্ত যা মার্জ কমিট সন্ধান করুন


181

নিম্নলিখিত ইতিহাসটি কল্পনা করুন:

       c---e---g--- feature
      /         \
-a---b---d---f---h--- master

কমিট "সি" মাস্টারের সাথে একত্রীকরণ হওয়ার পরে আমি কীভাবে খুঁজে পাব (যেমন, মার্জ কমিট "এইচ" সন্ধান করব)?

উত্তর:


156

আপনার উদাহরণটি দেখায় যে শাখাটি featureএখনও উপলব্ধ।

যে ক্ষেত্রে hশেষ ফলাফল:

git log master ^feature --ancestry-path

শাখা তাহলে featureআর পাওয়া যায় না, আপনার মধ্যে ইতিহাস লাইনে একত্রীকরণ করে দেখাতে পারেন cএবং master:

git log <SHA-1_for_c>..master --ancestry-path --merges

যদিও সব মার্জ যে পরে ঘটেছে দেখাবে hএবং তাদের মধ্যবর্তী eএবং gউপর feature


নিম্নলিখিত কমান্ডগুলির ফলাফলের সাথে তুলনা করা:

git rev-list <SHA-1_for_c>..master --ancestry-path

git rev-list <SHA-1_for_c>..master --first-parent

hসর্বশেষ সারি হিসাবে সাধারণভাবে আপনাকে SHA-1 দেবে ।

আপনার যদি এটি উপলব্ধ থাকে তবে আপনি comm -1 -2এই ফলাফলগুলিতে ব্যবহার করতে পারেন । আপনি যদি এমএসজিগিতে থাকেন তবে আপনি তুলনা করতে নিম্নলিখিত পার্ল কোডটি ব্যবহার করতে পারেন:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

( http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/ থেকে পার্ল কোড , যা এটি "কম.কমিক্স.শেল নিউজ গ্রুপের কেউ" থেকে নেওয়া হয়েছে)।

যদি আপনি এটিকে ওয়ান-লাইনার করতে চান তবে প্রক্রিয়াটির বিকল্পটি দেখুন ।


4
আপনার কম থাকলেও, আপনি এটি ব্যবহার করতে পারবেন না কারণ "গিট রেভ-লিস্ট" কমান্ডের আউটপুট অভিধানিকভাবে বাছাই করা হয়নি। আপনি অবশ্যই সাধারণ লাইনগুলি সন্ধান করার আগে প্রতিটি কমান্ডের আউটপুটটি বাছাই করতে পারেন, তবে তারপরে কাঙ্ক্ষিত প্রতিশ্রুতি অগত্যা শেষটি হবে না। সুতরাং আমি মনে করি পার্ল কমান্ডের মতো কিছু (যদিও অস্পষ্ট) প্রয়োজনীয়।
mhagger

12
আমি কেবল একটি স্ক্রিপ্ট গিট-উইল-মার্জ করে লিখেছি যা এই পরামর্শটি কার্যকর করে (বেশ কয়েকটি অন্যান্য বৈশিষ্ট্য সহ)। দেখুন github.com/mhagger/git-when-merged
mhagger

2
কিছু সময়ে ধরুন masterমধ্যে মিশে গিয়ে তৈরি হয় feature, তারপর অবিলম্বে featureমধ্যে মিশে গিয়ে তৈরি হয় masterফাস্ট এগিয়ে (ডগা যেমন featureপ্রতিস্থাপন master)। এর ফলে কি --first-parentভুল পিতামাতাকে ফিরিয়ে আনতে হবে?
ক্যালভিন

4
আমি চেষ্টা করেছি comm -1 -2কিন্তু কাজ হয়নি। commকেবল বাছাই করা লাইনে কাজ করে। (পার্ল ওয়ান-লাইনার কাজ করে, যদিও আমি এটি পড়তে পারি না))
ডোমন

2
এটি কিছুটা দেরিতে তবে যোগ করার ফলে লোকেরা এটিকে দরকারী হিসাবে খুঁজে পেতে পারে কারণ স্থানীয়ভাবে গিট এটি সরবরাহ করে না। এমন কয়েকটি কোণার মামলা রয়েছে যা আমি মনে করি এই উত্তরটি হ্যান্ডেল করে না (নীচে আমার উত্তর দেখুন stackoverflow.com/a/43716029/58678 যা বেশিরভাগ কোণার কেসগুলি পরিচালনা করে)। এখানে কোণার কেসগুলি রয়েছে: git find-merge h master(h প্রদান করা উচিত তবে কিছুই প্রত্যাবর্তন করে), git find-merge d master(রিটার্ন এফ তবে রিটার্ন করা উচিত d), git find-merge c feature(রিটার্ন ই তবে তবে জি ফিরে আসতে হবে)।
hIpPy

130

এটি আপনার যুক্ত করুন ~/.gitconfig:

[alias]
    find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
    show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"

তারপরে আপনি এর মতো উপকরণটি ব্যবহার করতে পারেন:

# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master

মার্জ কমিটের বার্তা এবং অন্যান্য বিশদটি দেখতে, ব্যবহার করুন git show-merge একই যুক্তি সহ ।

( গৌথিরের উত্তরের উপর ভিত্তি করে Rose রোজেন মাতেভ এবং জাভাব্রেটকে সমস্যাটি সংশোধন করার জন্য ধন্যবাদ sort))


6
সুন্দর! এটি সেরা ড্রপ-ইন সমাধান।
এন জোন্স

1
সচেতন হোন যে sort -k2 | uniq -f1 -d | sort -n | tail -1 | cut -f2সাধারণভাবে শেষের সারিটি সঠিকভাবে খুঁজে পাচ্ছে না। এটি ব্যর্থ হয় যেখানে একটি উদাহরণ এখানে
রোজেন মাতেভ

1
@ রোজেনমেটভ এটি 16db9fef5c581ab0c56137d04ef08ef1bf82b0b7আপনার পেস্টে চালানোর সময় এটি খুঁজে পায় , এটি কি প্রত্যাশিত নয়? আপনি কোন ওএস চালু করছেন?
রবিনস্ট

1
@ আরবিনস্ট, আপনার ঠিক আছে আমি "(জিএনইউ কোর্টিলস) 8.4" পেয়েছি এবং আমার জন্য এটি খুঁজে পেয়েছে29c40c3a3b33196d4e79793bd8e503a03753bad1
রোজেন মেটেভ

2
@ পাওলো: কিছুই নয়, সুবিধার জন্য এটি দুটিয়ের পরিবর্তে কেবল একটি কমান্ড।
রবিনস্ট

28

গিট-গেট-মার্জটি সন্ধান করবে এবং আপনি যে সংযুক্তিটি সন্ধান করছেন তা প্রদর্শন করবে:

pip install git-get-merge
git get-merge <SHA-1>

কমান্ড প্রদত্ত প্রতিশ্রুতিবদ্ধদের সন্তানদের অনুসরণ করে যতক্ষণ না অন্য শাখায় (সম্ভবত মাস্টার) একীভূত হয়


22

অর্থাৎ গৌথিরের পোস্টটির সংক্ষিপ্তসার জানাতে:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' <(git rev-list --ancestry-path <SHA-1_for_c>..master) <(git rev-list --first-parent <SHA-1_for_c>..master) | tail -n 1

সম্পাদনা করুন: কারণ এটি প্রক্রিয়া প্রতিস্থাপন " <()" ব্যবহার করে , এটি পসিক্সের সাথে সামঞ্জস্যপূর্ণ নয় এবং এটি আপনার শেলের সাথে কাজ নাও করতে পারে। এটি সঙ্গে bashবা zshযদিও কাজ করে ।


4
আমি প্রায়শই ইন্টারনেট থেকে কোড অনুলিপি / পেস্ট করি না, তবে আমি যখন এটি করি নিখুঁতভাবে কাজ করে! আমাকে ভাবতে না দেওয়ার জন্য ধন্যবাদ টোটার।
বেন

2
@ থিওডোরআর.স্মিত দুর্ভাগ্যক্রমে, সিনট্যাক্সটি <()পসিক্স সামঞ্জস্যপূর্ণ নয়। আপনার ব্যবহার করতে হবে bash, zshবা একটি শেল সমর্থনকারী প্রক্রিয়া বিকল্পের প্রয়োজন । আমি আমার উত্তর অনুসারে সম্পাদনা করেছি।
টোটার

আমার পক্ষে কাজ করেনি। আমি মনে করি যে আমার বৈশিষ্ট্য শাখাটি মাস্টারটিতে মার্জ হওয়ার আগে প্রথমে অন্য কোনও শাখায় মার্জ হয়েছিল। এটি ব্যাখ্যা করতে পারে যে আপনার আদেশগুলি "মার্জ শাখা 'বৈশিষ্ট্য_ব্রঞ্চ' এর পরিবর্তে" মার্জ শাখা 'রিলিজ_ব্রঞ্চ' "এ ফলাফল দেয়।
টিম কুইপার্স

14

আমার এটি করার দরকার ছিল এবং কোনওভাবে খুঁজে পেয়েছি git-when-merged(যা আসলে এই SO প্রশ্নের উল্লেখ করে তবে মাইকেল হ্যাগার্টি এখানে তার খুব সুন্দর পাইথন লিপির কোনও রেফারেন্স যোগ করেনি)। তাই এখন আমার আছে।


আমি আসলে তার পৃষ্ঠা থেকে এই প্রশ্নে এসেছি।
ফ্ল্যাভিয়াস

12

গৌথিরের দুর্দান্ত উত্তরের ভিত্তিতে, commতালিকাগুলির তুলনা করতে আমাদের প্রয়োজন হবে না । যেহেতু আমরা শেষ ফলাফলটি সন্ধান করছি --ancestry-pathযার মধ্যে এটিও রয়েছে --first-parent, আমরা সহজেই প্রাক্তনটির ফলাফলের জন্য গ্রেপ করতে পারি:

git rev-list <SHA>..master --ancestry-path | grep -f <(git rev-list <SHA>..master --first-parent) | tail -1

বা চটজলদি এবং পুনঃব্যবহারযোগ্য কোনও কিছুর জন্য, এখানে পপ করার জন্য একটি ফাংশন এখানে রয়েছে .bashrc:

function git-find-merge() {
  git rev-list $1..master --ancestry-path | grep -f <(git rev-list $1..master --first-parent) | tail -1
}

এটি আমার পক্ষে কাজ করেছে। commইনপুটগুলি বাছাই করা না হলে কাজ করেনি।
hIpPy


4

আমি নীচে বাশ স্ক্রিপ্ট ব্যবহার করি যা আমি পথে রাখি ~/bin/git-find-merge। এটি গৌথিরের উত্তর এবং কর্নারের কেসগুলি পরিচালনা করার জন্য কয়েকটি টুইটের সাথে দুষ্টু স্তরের জবাবের ভিত্তিতে । commইনপুটগুলি বাছাই না করা হলে ছোঁড়ে। grep -fপুরোপুরি কাজ করে।

কোণার কেস:

  • কমিট যদি শাখার প্রথম-পিতামাতার পথে একীভূত প্রতিশ্রুতি হয় তবে কমিট রিটার্ন করুন।
  • কমিট যদি শাখার প্রথম-পিতা-মাতার পথে অন-মার্জ কমিট হয় তবে শাখাটি ফেরত দিন। এটি হয় একটি এফএফ মার্জ বা প্রতিশ্রুতি শুধুমাত্র শাখায় এবং সঠিক কমিট খুঁজে বের করার কোনও ভাল উপায় নেই।
  • যদি কমিট এবং শাখা একই থাকে তবে কমিট রিটার্ন করুন।

~/bin/git-find-merge লিপি:

#!/bin/bash

commit=$1
if [ -z $commit ]; then
    echo 1>&2 "fatal: commit is required"
    exit 1
fi
commit=$(git rev-parse $commit)
branch=${2-@}

# if branch points to commit (both are same), then return commit
if [ $commit == $(git rev-parse $branch) ]; then
    git log -1 $commit
    exit
fi

# if commit is a merge commit on first-parent path of branch,
# then return commit
# if commit is a NON-merge commit on first-parent path of branch,
# then return branch as it's either a ff merge or commit is only on branch
# and there is not a good way to figure out the right commit
if [[ $(git log --first-parent --pretty='%P' $commit..$branch | \
    cut -d' ' -f1 | \
    grep $commit | wc -l) -eq 1 ]]; then
    if [ $(git show -s --format="%P" $commit | wc -w) -gt 1 ]; then
        # if commit is a merge commit
        git log -1 $commit
    else
        # if commit is a NON-merge commit
        echo 1>&2 ""
        echo 1>&2 "error: returning the branch commit (ff merge or commit only on branch)"
        echo 1>&2 ""
        git log -1 $branch
    fi
    exit
fi

# 1st common commit from bottom of first-parent and ancestry-path
merge=$(grep -f \
    <(git rev-list --first-parent  $commit..$branch) \
    <(git rev-list --ancestry-path $commit..$branch) \
        | tail -1)
if [ ! -z $merge ]; then
    git log -1 $merge
    exit
fi

# merge commit not found
echo 1>&2 "fatal: no merge commit found"
exit 1

যা আমাকে এটি করতে দেয়:

(master)
$ git find-merge <commit>    # to find when commit merged to current branch
$ git find-merge <branch>    # to find when branch merged to current branch
$ git find-merge <commit> pu # to find when commit merged to pu branch

এই স্ক্রিপ্টটি আমার গিথুবেও উপলভ্য ।


2
git log --topo-order

তারপরে কমিট করার আগে প্রথম সংযুক্তির সন্ধান করুন।


1

@ রবিনস্টের ধারণার আমার রুবি সংস্করণটি দ্বিগুণ দ্রুত কাজ করে (যা খুব পুরানো প্রতিশ্রুতি সন্ধানের জন্য গুরুত্বপূর্ণ)।

find-commit.rb

commit = ARGV[0]
master = ARGV[1] || 'origin/master'

unless commit
  puts "Usage: find-commit.rb commit [master-branch]"
  puts "Will show commit that merged <commit> into <master-branch>"
  exit 1
end

parents = `git rev-list #{commit}..#{master} --reverse --first-parent --merges`.split("\n")
ancestry = `git rev-list #{commit}..#{master} --reverse --ancestry-path --merges`.split("\n")
merge = (parents & ancestry)[0]

if merge
  system "git show #{merge}"
else
  puts "#{master} doesn't include #{commit}"
  exit 2
end

আপনি এটি কেবল এটির মতো ব্যবহার করতে পারেন:

ruby find-commit.rb SHA master

0

আপনি এরকম কিছু চেষ্টা করতে পারেন। সমস্ত মার্জ কমিটের মাধ্যমে ধারণাটি পুনরাবৃত্তি করতে হবে এবং দেখুন যে "কম" প্রতিশ্রুতি তাদের মধ্যে থেকে পৌঁছানো যায় কিনা:

$ git log --merges --format='%h' master | while read mergecommit; do
  if git log --format='%h' $mergecommit|grep -q $c; then
    echo $mergecommit;
    break
  fi
done

এটি এর মতো:git rev-list <SHA-1_for_c>..master --ancestry-path --merges
ইউজেন কনকভ

0

আমাকে বেশ কয়েকবার এটি করতে হয়েছিল (যারা এই প্রশ্নের উত্তর দিয়েছেন তাদের সবাইকে ধন্যবাদ!), এবং একটি স্ক্রিপ্ট (গৌথিরের পদ্ধতি ব্যবহার করে) লিখে শেষ করেছিলাম যা আমি আমার সামান্য গিটার ইউটিলিটিগুলিতে সংগ্রহ করতে পারি। আপনি এটি এখানে খুঁজে পেতে পারেন: https://github.com/mwoehlke/git-utils/blob/master/bin/git- विसর- পয়েন্ট

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.