গিট শাখার নিকটতম পিতামাতাকে কীভাবে খুঁজে পাবেন?


419

ধরা যাক, আমার কাছে এর মতো কমিট ট্রি সহ নিম্নলিখিত স্থানীয় সংগ্রহস্থল রয়েছে:

master --> a
            \
             \
      develop c --> d
               \
                \
         feature f --> g --> h

masterআমার হয় এই হয় সর্বশেষ স্থিতিশীল মুক্তি কোড , developআমার এই 'পরবর্তী' মুক্তি কোড , এবং featureহয় একটি নতুন বৈশিষ্ট্য জন্য প্রস্তুত করা হচ্ছেdevelop

হুক ব্যবহার করে আমার রিমোট রেপোতে আমি যা করতে সক্ষম হতে চাই featureতা যদি fহ'ল প্রত্যক্ষ বংশধর না হয় তবে তা অস্বীকার করা উচিত develop। অর্থাৎ ভালো গাছ সৌন্দর্য কমিট কারন বৈশিষ্ট্যটি হয়েছে git rebaseউপর d

master --> a
            \
             \
      develop c --> d
                     \
                      \
               feature f --> g --> h

সুতরাং এটি সম্ভব:

  • এর মূল শাখাটি শনাক্ত করুন feature?
  • অভিভাবক শাখায় অঙ্গীকার শনাক্ত করুন কোনটির fবংশধর?

সেখান থেকে আমি পিতামাত শাখার প্রধান কি তা যাচাই করে দেখব এবং fপূর্বসূরি প্যারেন্ট ব্রাঞ্চ হেডের সাথে মেলে কিনা, তা নির্ধারণের জন্য বৈশিষ্ট্যটি পুনরায় সেট করা দরকার কিনা।


এই প্রশ্নটি কোনও পিতামাতার পিতামাতার সন্ধানের জন্য পুনর্বিবেচনা করা উচিত।
টিম বোল্যান্ড

উত্তর:


347

ধরে নিই যে দূরবর্তী সংগ্রহস্থলের বিকাশকারী শাখার একটি অনুলিপি রয়েছে (আপনার প্রাথমিক বিবরণটি স্থানীয় সংগ্রহস্থলে এটি বর্ণনা করে তবে এটি রিমোটে উপস্থিত রয়েছে বলে মনে হয়), আপনি যা চান তা আপনি অর্জন করতে সক্ষম হবেন, তবে পদ্ধতিটি আপনি যা কল্পনা করেছেন তার থেকে কিছুটা আলাদা।

গিটের ইতিহাস কমিটের একটি ডাগের উপর ভিত্তি করে। শাখা (এবং সাধারণভাবে "রেফ") কেবলমাত্র ক্ষণস্থায়ী লেবেল যা ক্রমাগত ক্রমবর্ধমান কমিট ডিএজি-তে নির্দিষ্ট কমিটগুলির প্রতি নির্দেশ করে। সেই হিসাবে, শাখাগুলির মধ্যে সম্পর্ক সময়ের সাথে সাথে পরিবর্তিত হতে পারে তবে কমিটগুলির মধ্যে সম্পর্কটি হয় না।

    ---o---1                foo
            \
             2---3---o      bar
                  \
                   4
                    \
                     5---6  baz

দেখে মনে bazহচ্ছে এটি (পুরানো সংস্করণ) ভিত্তিক bar? তবে আমরা যদি মুছতে barপারি?

    ---o---1                foo
            \
             2---3
                  \
                   4
                    \
                     5---6  baz

এখন দেখে মনে হচ্ছে bazএটি ভিত্তিক foo। তবে পূর্বপুরুষের bazকোনও পরিবর্তন হয়নি, আমরা কেবল একটি লেবেল সরিয়েছি (এবং ফলস্বরূপ ঝুঁকির প্রতিশ্রুতি)। এবং যদি আমরা একটি নতুন লেবেল যুক্ত করি 4?

    ---o---1                foo
            \
             2---3
                  \
                   4        quux
                    \
                     5---6  baz

এখন দেখে মনে হচ্ছে bazএটি ভিত্তিক quux। তবুও পূর্বপুরুষের কোনও পরিবর্তন হয়নি, কেবলমাত্র লেবেলগুলির পরিবর্তন হয়েছে।

তবে, আমরা যদি জিজ্ঞাসা করতাম যে "প্রতিশ্রুতির 6বংশধর প্রতিশ্রুতিবদ্ধ 3?" (ধরে নিলাম 3এবং 6সম্পূর্ণ SHA-1 প্রতিশ্রুতিবদ্ধ নামগুলি রয়েছে), তারপরে উত্তরটি "হ্যাঁ" হবে, এটি barএবং quuxলেবেল উপস্থিত রয়েছে কি না।

সুতরাং, আপনি প্রশ্নগুলি জিজ্ঞাসা করতে পারেন যেমন "ধাক্কা দেওয়া কি বিকাশকারী শাখার বর্তমান নূরের বংশধরকে প্রতিশ্রুতিবদ্ধ?", তবে আপনি নির্ভরযোগ্যভাবে জিজ্ঞাসা করতে পারবেন না "ধাক্কা দেওয়ার প্রতিশ্রুতির মূল শাখাটি কি?"

বেশিরভাগ নির্ভরযোগ্য একটি প্রশ্ন যা আপনি যা চান তার কাছে চলে আসে বলে মনে হচ্ছে:

সমস্ত ধাক্কা কমিটের পূর্বপুরুষদের জন্য ( বিকাশের বর্তমান টিপ এবং এর পূর্বপুরুষদের বাদে ), যার পিতামাতার হিসাবে বিকাশের বর্তমান টিপ রয়েছে :

  • কমপক্ষে এরকম একটি প্রতিশ্রুতি আছে কি?
  • এই জাতীয় সবকটি কি একক-পিতামাতার কমিট করে?

যা প্রয়োগ করা যেতে পারে:

pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1
fi
parents_of_children_of_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -F "$baserev"
)"
case ",$parents_of_children_of_base" in
    ,)     echo "must descend from tip of '$basename'"
           exit 1 ;;
    ,*\ *) echo "must not merge tip of '$basename' (rebase instead)"
           exit 1 ;;
    ,*)    exit 0 ;;
esac

এটি আপনি সীমাবদ্ধ রাখতে চান এমন কিছুকে কভার করবে, তবে সব কিছুই হতে পারে না।

রেফারেন্সের জন্য, এখানে একটি বর্ধিত উদাহরণ ইতিহাস:

    A                                   master
     \
      \                    o-----J
       \                  /       \
        \                | o---K---L
         \               |/
          C--------------D              develop
           \             |\
            F---G---H    | F'--G'--H'
                    |    |\
                    |    | o---o---o---N
                     \   \      \       \
                      \   \      o---o---P
                       \   \   
                        R---S

উপরের কোড প্রত্যাখ্যান করার ব্যবহার করা যেতে পারে Hএবং Sযখন গ্রহণ H', J, K, অথবা N, কিন্তু এটি মেনে নেবেন Lএবং P(তারা মার্জ জড়িত, কিন্তু তারা ডগা একত্রীকরণ না বিকাশ )।

এছাড়াও প্রত্যাখ্যান করতে Lএবং P, আপনি প্রশ্নটি পরিবর্তন করে জিজ্ঞাসা করতে পারেন

সমস্ত ধাক্কা কমিটের পূর্বপুরুষদের জন্য ( বিকাশের বর্তমান টিপ এবং এর পূর্বপুরুষদের বাদে ):

  • দু'জন বাবা-মায়ের সাথে কি কোনও কমিট আছে?
  • যদি তা না হয় তবে কমপক্ষে একটি কমিটের কি তার (একমাত্র) পিতামাতাকে বিকাশের বর্তমান টিপ আছে ?
pushedrev=...
basename=develop
if ! baserev="$(git rev-parse --verify refs/heads/"$basename" 2>/dev/null)"; then
    echo "'$basename' is missing, call for help!"
    exit 1
fi
parents_of_commits_beyond_base="$(
  git rev-list --pretty=tformat:%P "$pushedrev" --not "$baserev" |
  grep -v '^commit '
)"
case "$parents_of_commits_beyond_base" in
    *\ *)          echo "must not push merge commits (rebase instead)"
                   exit 1 ;;
    *"$baserev"*)  exit 0 ;;
    *)             echo "must descend from tip of '$basename'"
                   exit 1 ;;
esac

আমি এটি পেয়েছি: গিট: মারাত্মক: অস্পষ্ট যুক্তি '...': সংশোধন এবং ফাইলের নাম উভয়ই। ট্রিপল ডটসের উদ্দেশ্য কী?
জ্যাক উকলেজা

1
@ স্নাইডার আমি নিশ্চিত '' ... 'উদাহরণস্বরূপ একজন স্থানধারক হিসাবে প্রতিষ্ঠিত হয়েছে: আপনি যদি এটি প্রতিস্থাপনের এসএএএর সাথে প্রতিস্থাপন করেন তবে আপনি এই চেকটি সম্পাদনের চেষ্টা করছেন (বলুন, শাখার প্রধান আপনি বর্তমানে চালু আছেন), সবকিছু ঠিকঠাক কাজ করে।
ড্যানিয়েল ব্র্যাডি

এই বিস্তৃত উত্তরের জন্য ধন্যবাদ! এটি সুপার দরকারী। আমি একটি অনুরূপ হুক করতে চাই, তবে আমি উন্নয়ন শাখার নামটি হার্ড-কোড করতে চাই না। অর্থ আমি পিতামাতার শাখা ব্যতীত অন্য কোনও শাখায় পুনর্বাসনের প্রতিরোধের জন্য একটি হুক চাই। যদি আমি আপনার উত্তরটি ভালভাবে বুঝতে পারি (আমি ব্যাশ এবং স্টাফের জন্য নতুন) তবে এটি আপনার উত্তরে notাকা হয়নি, তাই না? এই কাজ করতে একটি উপায় আছে কি?
কেমেয়া

আপনি কি কোনও সম্পর্কিত প্রশ্নের উত্তর দিতে রাজি? আমি আপনার কোডটি একটি রিমোটো সংগ্রহস্থলে কাজ করতে সক্ষম হইনি। : এখানে কিভাবে একটি দূরবর্তী সংগ্রহস্থল সঙ্গে কাজ করার আপনার পদক্ষেপ খাপ খাওয়ানো সম্পর্কে ফলো-আপ প্রশ্ন লিংক stackoverflow.com/questions/49619492/...
CodeMed

আমার যখন ছিল তখন এটি আমার পক্ষে কাজ করে না develop > release > feature, আমি আবার বিকাশ লাভ করব এবং এটির জন্য পিতামাতার জানা দরকার। আমার সমস্যা সমাধান ছিল stackoverflow.com/a/56673640/2366390
verdverm

240

একটি রিফ্র্যাসাল

প্রশ্নের বাক্যটির আরেকটি উপায় হ'ল "নিকটবর্তী অঙ্গীকারটি কী যা বর্তমান শাখা বাদে অন্য কোনও শাখায় থাকে এবং কোন শাখাটি এটি?"

একটি সমাধান

আপনি এটি কমান্ড লাইন ম্যাজিকের কিছুটা দিয়ে খুঁজে পেতে পারেন

git show-branch \
| sed "s/].*//" \
| grep "\*" \
| grep -v "$(git rev-parse --abbrev-ref HEAD)" \
| head -n1 \
| sed "s/^.*\[//" 

সঙ্গে awk :

git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/[^\[]*//' \
| awk 'match($0, /\[[a-zA-Z0-9\/-]+\]/) { print substr( $0, RSTART+1, RLENGTH-2 )}'

এখানে কিভাবে এটা কাজ করে:

  1. দূরবর্তী শাখাসহ সকল কমিটের একটি পাঠ্য ইতিহাস প্রদর্শন করুন।
  2. বর্তমান অঙ্গীকারের পূর্বসূরীরা একটি তারকা দ্বারা নির্দেশিত। সমস্ত কিছু ফিল্টার আউট।
  3. বর্তমান শাখায় সমস্ত কমিট উপেক্ষা করুন।
  4. প্রথম ফলাফলটি নিকটতম পূর্বপুরুষের শাখা হবে। অন্যান্য ফলাফল উপেক্ষা করুন।
  5. শাখার নামগুলি [বন্ধনীগুলিতে] প্রদর্শিত হয়। বন্ধনী এবং বন্ধনীগুলির বাইরে সমস্ত কিছু উপেক্ষা করুন।
  6. কখনও কখনও শাখার নাম একটি ~ # বা ^ # অন্তর্ভুক্ত করে নির্দেশিত প্রতিশ্রুতিবদ্ধ এবং শাখা টিপের মধ্যে কতগুলি কমিট হয় তা নির্দেশ করে। আমাদের কিছু যায় আসে না। তাদের উপেক্ষা.

এবং ফলাফল

উপরের কোডটি চালু রয়েছে

 A---B---D <-master
      \
       \
        C---E---I <-develop
             \
              \
               F---G---H <-topic

আপনি developযদি এইচ থেকে চালনা করেন এবং masterআপনি যদি এটি আই থেকে চালান তবে আপনাকে দেবে

কোডটি গিস্ট হিসাবে উপলব্ধ


24
পিছনে থাকা ব্যাকটিকটি সরানো হয়েছে যা ত্রুটির কারণ হয়েছিল। যদিও এই আদেশটি চালানোর সময়, আমি বিপুল পরিমাণে সতর্কতা পেয়েছি, প্রতিটি শাখা সম্পর্কে অভিযোগ করে বলছিcannot handle more than 25 refs
জন এল।

1
@ জো ক্রাইসলার আপনি কী ভাবেন যে আপনি এটি 2 এর পরিবর্তে একটি লাইন তৈরি করতে পারবেন এবং ম্যাকের জন্য এটি ম্যাকের ackজন্য উপলব্ধ নয় যেমন এটি ব্যবহার করা সম্ভব (কারও ackসাথে প্রতিস্থাপনের প্রস্তাব দেওয়া হয়েছে grep)
ননপোলারিটি

53
দুঃখিত, একটি ভুল আছে। এখানে আমার জন্য সঠিকভাবে কাজ করেছেন:git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
droidbot

15
@ড্রয়েডবট নিস, তবে যখন গ্রেপ-ভি ক্যাচ কমিট ম্যাসেজ দেয় বা আপনার শাখার নাম অন্য কোনও শাখার নামের অংশ হয় তখন রেফগুলি অপসারণ এড়াতে পাইপিং পুনর্নির্মাণের দরকার হয়। git show-branch | sed "s/].*//" | grep "\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/^.*\[//"
গাল

3
@ ওলেগআব্রাহাভায়েভ আপনার প্রশ্নের উত্তর পেয়েছে কিনা তা আমি জানি না। এর গিট ওরফে ব্যবহার করে: parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"আমার জন্য কাজ করে
mduttondev

111

আপনিও চেষ্টা করতে পারেন:

git log --graph --decorate

5
git log --graph --decorate --simplify-by-decorationwhere --graphচ্ছিক যেখানে ।
Na13-c

1
git log --graph --decorate --simplify-by-decoration --oneline
anishtain4

106

গিট প্যারেন্ট

আপনি কেবল কমান্ড চালাতে পারেন

git parent

শাখার পিতামাতাকে সন্ধান করতে, আপনি যদি @ জো ক্রাইসলারের উত্তরটি গিট ওরফে হিসাবে যুক্ত করেন । এটি ব্যবহারকে সহজতর করবে।

যে "~/.gitconfig"কোনও পাঠ্য সম্পাদক ব্যবহার করে অবস্থিত gitconfig ফাইলটি খুলুন । (লিনাক্সের জন্য)। এবং উইন্ডোজের জন্য ".gitconfig" পাথটি সাধারণত অবস্থিতc:\users\your-user\.gitconfig

vim  ~/.gitconfig

ফাইলের মধ্যে নিম্নলিখিত উপন্যাস কমান্ড যুক্ত করুন:

[alias]
            parent = "!git show-branch | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"

সম্পাদকটি সংরক্ষণ করুন এবং প্রস্থান করুন।

কমান্ড চালান git parent

এটাই!


5
এটি একটি দুর্দান্ত সমাধান। প্রত্যাশিত ফলাফল নিশ্চিত হওয়ার জন্য কিছু নমুনা আউটপুট যুক্ত করাও সহায়ক হবে be আমি যখন এটি চালিয়েছি তখন আমি শেষ পংক্তির আগে কিছু সতর্কতা পেয়েছিলাম যা আমি বিশ্বাস করি যে অভিভাবক শাখার নাম।
ttemple

4
একটি যাদুমন্ত্র মত কাজ করে! উইন্ডোজ ব্যবহারকারীদের জন্য .gitconfig সাধারণত গ অবস্থিত: \ ব্যবহারকারী \ আপনার ব্যবহারকারী \ .gitconfig
সিয়োনে

12
পথ cannot handle more than 25 refsব্যতিক্রম।
শাজিন

সতর্কতাটি পরিচালনা করতে কেউ কি এটি সম্পাদনা করতে পারে? @ টিটেম্পল, আপনি পারবেন?
নিখিল সিএম

@ নিখিলসিএম একটি চ্যাম্পিয়ন এর মতো কাজ করে। তবে আমার এখানে একটি প্রশ্ন রয়েছে যে পিতামাতারা কোথা থেকে শাখাটি তৈরি করেছেন বা অন্য কিছু থেকে বোঝায়?
হরিপ্রসথ

52

আমি আপনার সামগ্রিক সমস্যার একটি সমাধান আছে (নির্ধারণ যদি featureডগা থেকে অবতীর্ণ হয় develop), কিন্তু এটা পদ্ধতি রূপরেখা ব্যবহার কাজ করে না।

আপনি git branch --containsসমস্ত শাখার শীর্ষ থেকে নেমে আসা সমস্ত শাখার তালিকা তৈরি করতে ব্যবহার করতে পারেন develop, তারপরে তাদের মধ্যে রয়েছে grepকিনা featureতা নিশ্চিত করে ব্যবহার করুন।

git branch --contains develop | grep "^ *feature$"

এটি যদি তাদের মধ্যে থাকে তবে এটি " feature"স্ট্যান্ডার্ড আউটপুটে মুদ্রণ করবে এবং এর একটি রিটার্ন কোড থাকবে Otherwise অন্যথায়, এটি কিছুই প্রিন্ট করবে না এবং 1 এর একটি রিটার্ন কোড থাকবে।


1
এটি কাজ করে তবে এটি লক্ষণীয় হওয়া উচিত যে প্রচুর পরিমাণে রিপোসেটরিতে এটি দীর্ঘ সময় নিতে পারে। এটি এটিকে চালানোর জন্য আদর্শের চেয়ে কিছুটা কম করে তোলে, উদাহরণস্বরূপ, প্রাক-গ্রহণের হুক।
ebneter

আমি শাখাটি খুঁজছিলাম, আমরা এটি কল করব <branch>, যেখানে আমি সঞ্চালন করেছি: git checkout -b <branch-2>থেকে ... এই উত্তরটিই! সত্যিই, গ্রেপের দরকার নেই। git branch --contains <branch>
পপি ম্যাকফার্টনয়েস

44

এটা আমার জন্য কাজ করে।

git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

সৌজন্য উত্তরগুলি: @ড্রয়েডবট এবং @ জিসিডিডিওট


হ্যাঁ, তবে কখনও কখনও এটি গ্রেপ থেকে "ভাঙা পাইপ" পেয়ে যায়।
ভ্লাদিস্লাভ রাস্ট্রুসনি

1
*গ্রেপ পাস করার জন্য একটি সঠিক রেজেক্স নয়। ব্যবহার করা উচিত grep -F '*'বা grep '\*'পরিবর্তে। অন্যথায় ভাল সমাধান।
আরিফ

আমি কোন আউটপুট পাইনি।
সন্দীপ সুবেদী

আমার জন্য কাজ করে ....
রুট ট্রাভেলার

11

যেহেতু উপরের উত্তরগুলির কোনওটিই আমাদের সংগ্রহশালায় কাজ করেনি, সর্বশেষ সংযুক্তিতে আমি নিজের মতো করে ভাগ করতে চাই git log:

#!/bin/bash
git log --oneline --merges "$@" | grep into | sed 's/.* into //g' | uniq --count | head -n 10

এটিকে নামের স্ক্রিপ্টে রাখুন git-last-merges, যা অন্য কোনও শাখার নামকে তর্ক হিসাবে (বর্তমান শাখার পরিবর্তে) স্বীকার করেgit log যুক্তি

আউটপুট থেকে, আমরা নিজস্ব ব্রাঞ্চিং কনভেনশন এবং প্রতিটি শাখা থেকে একত্রীকরণের সংখ্যার ভিত্তিতে প্যারেন্ট ব্রাঞ্চ (এস) ম্যানুয়ালি সনাক্ত করতে পারি।

সম্পাদনা: আপনি যদি git rebaseশিশু শাখাগুলিতে প্রায়শই ব্যবহার করেন (এবং মার্জগুলি প্রায়শই ফোর-ফরওয়ার্ড করা হয় তবে অনেকগুলি মার্জ কমিট হয় না), এই উত্তরটি ভাল কাজ করবে না, তাই আমি সামনের কমিটগুলি গণনা করার জন্য একটি স্ক্রিপ্ট লিখেছিলাম (স্বাভাবিক এবং মার্জ) এবং বর্তমান শাখার সাথে তুলনা করে সমস্ত শাখায় কমিটের পিছনে (প্যারেন্ট শাখায় মার্জ হওয়ার পিছনে কোনও হওয়া উচিত নয়)। কেবল এই স্ক্রিপ্টটি চালান এবং আপনার পক্ষে কাজ করে কিনা তা আমাকে জানান

#!/bin/bash
HEAD="`git rev-parse --abbrev-ref HEAD`"
echo "Comparing to $HEAD"
printf "%12s  %12s   %10s     %s\n" "Behind" "BehindMerge" "Ahead" "Branch"
git branch | grep -v '^*' | sed 's/^\* //g' | while read branch ; do
    ahead_merge_count=`git log --oneline --merges $branch ^$HEAD | wc -l`
    if [[ $ahead_merge_count != 0 ]] ; then
        continue
    fi
    ahead_count=`git log --oneline --no-merges $branch ^$HEAD | wc -l`
    behind_count=`git log --oneline --no-merges ^$branch $HEAD | wc -l`
    behind_merge_count=`git log --oneline --merges ^$branch $HEAD | wc -l`
    behind="-$behind_count"
    behind_merge="-M$behind_merge_count"
    ahead="+$ahead_count"
    printf "%12s  %12s   %10s     %s\n" "$behind" "$behind_merge" "$ahead" "$branch"
done | sort -n

ধন্যবাদ। যদিও আপনি rebaseপ্রায়শই ব্যবহার করেন (এবং মার্জগুলি fast-forwardপ্রায়শই এড হয়) তবে এটি খুব ভাল কাজ করতে পারে না । এর থেকে আরও ভাল সমাধান পেলে আমি আমার উত্তরটি সম্পাদনা করব।
সাeedদগ্নু

1
একমাত্র? এখন পর্যন্ত উত্তর যা আমার পক্ষে সংবেদনশীলভাবে কাজ করেছে সেই ক্ষেত্রে যেখানে বর্তমান শাখাটি মাস্টার। বেশিরভাগ অন্যান্য সমাধানগুলি এলোমেলোভাবে প্রান্তের ক্ষেত্রে একটি এলোমেলো (এবং পরিষ্কারভাবে ভুল) ফলাফল দেয় যেখানে সত্যিকারের প্যারেন্ট শাখা নেই।
আরিফ

এটি আমার পক্ষে কাজ করা একমাত্র উত্তর। প্রথম 10 টির তালিকার পরিবর্তে প্রথম পিতামাতা পেতে আপনি এটি ব্যবহার করতে পারেন: git log --oneline --merges "$@" | grep into | sed 's/.* into //g' | uniq --count | head -n 1 | cut -d ' ' -f 8
প্রচুর লগ

10

একটি সমাধান

ভিত্তিকgit show-branch সমাধানটি আমার পক্ষে বেশিরভাগ ক্ষেত্রে কার্যকর হয়নি (নীচে দেখুন), সুতরাং আমি এটি ভিত্তিকgit log সাথে একত্রিত করেছি এবং এটি দিয়ে শেষ করেছি:

git log --decorate --simplify-by-decoration --oneline \ # selects only commits with a branch or tag
      | grep -v "(HEAD" \                               # removes current head (and branch)
      | head -n1 \                                      # selects only the closest decoration
      | sed 's/.* (\(.*\)) .*/\1/' \                    # filters out everything but decorations
      | sed 's/\(.*\), .*/\1/' \                        # picks only the first decoration
      | sed 's/origin\///'                              # strips "origin/" from the decoration

সীমাবদ্ধতা এবং গুহাত

  • হেডকে আলাদা করা যায় (একটি নির্দিষ্ট শাখায় তারা সঠিক প্রতিশ্রুতি তৈরি করতে তা নিশ্চিত করতে অনেক সিআই সরঞ্জামগুলি এটি করে) তবে মূল শাখা এবং স্থানীয় শাখা উভয়ই সমান বা "উপরে" থাকতে হবে বর্তমান হেড হবে।
  • কোনও ট্যাগ থাকতে হবে না (আমার ধারণা; আমি বাচ্চা এবং অভিভাবক শাখার মধ্যে একটি ট্যাগ দিয়ে কমপিটে স্ক্রিপ্টটি পরীক্ষা করি নি)
  • স্ক্রিপ্টটি "হেড" সর্বদা কমান্ড দ্বারা প্রথম সজ্জা হিসাবে তালিকাভুক্ত করা হয় তার উপর নির্ভর করেlog
  • চলমান স্ক্রিপ্ট উপর masterএবংdevelop ফলাফল (বেশিরভাগই) এ<SHA> Initial commit

ফলাফলগুলো

 A---B---D---E---F <-origin/master, master
      \      \
       \      \
        \      G---H---I <- origin/hotfix, hotfix
         \
          \
           J---K---L <-origin/develop, develop
                \
                 \
                  M---N---O <-origin/feature/a, feature/a
                       \   \
                        \   \
                         \   P---Q---R <-origin/feature/b, feature/b
                          \
                           \
                            S---T---U <-origin/feature/c, feature/c

স্থানীয় শাখার অস্তিত্ব থাকা সত্ত্বেও (উদাহরণস্বরূপ কেবলমাত্র origin/topicউপস্থিত থাকে যেহেতু Oকমিটটি সরাসরি তার এসএইচএ দ্বারা চেক আউট করা হয়েছিল), স্ক্রিপ্টটি নিম্নরূপে মুদ্রণ করা উচিত:

  • করে জন্য G, H,I (শাখা hotfix) →master
  • করে জন্য M, N,O (শাখা feature/a) →develop
  • করে জন্য S, T,U (শাখা feature/c) →develop
  • করে জন্য P, Q,R (শাখা feature/b) →feature/a
  • করে জন্য J, K, L(শাখা develop) → <sha> Initial commit*
  • করে জন্য B, D, E, F(শাখা master) →<sha> Initial commit

* - বা masterযদি developকমিটগুলি মাস্টারের হেডের শীর্ষে থাকে (master মাস্টারটি বিকাশের জন্য দ্রুত এগিয়ে যেতে সক্ষম হবে)


আমার জন্য কেন শাখা-শাখা কাজ করেনি

ভিত্তিকgit show-branch সমাধান নিম্নলিখিত পরিস্থিতিতে আমার জন্য অবিশ্বাস্য প্রমাণিত:

  • বিচ্ছিন্ন হেড - বিচ্ছিন্ন হেড কেস সহ মানে grep '\*' \`গ্রেপ'র পরিবর্তে ! ' \ - এবং এটি সমস্ত সমস্যার শুরু মাত্র
  • চলমান স্ক্রিপ্ট উপর masterএবংdevelop ফলাফল developযথাক্রমে এবং ``
  • শাখায়master ( hotfix/শাখা) শাখাগুলি developপিতামাতার সাথে শেষ হয় কারণ তাদের নিকটতম masterশাখার পিতা-মাতার কারণের !পরিবর্তে চিহ্নিত করা হয়েছিল *

2
কেবল উত্তরটি কাজ করেছিল - গিট গিরির উপন্যাস হিসাবে:"!git log --decorate --simplify-by-decoration --oneline | grep -v '(HEAD' | head -n1 | sed 's/.* (\\(.*\\)) .*/\\1/' | sed 's/\\(.*\\), .*/\\1/' | sed 's/origin\\///'"
ইয়ান কেম্প

8

মনে রাখবেন যে, "গিট: কমিট কোন শাখাটি এসেছে তা আবিষ্কার করা" তে বর্ণিত হিসাবে আপনি যে শাখাটি করেছিলেন সে শাখাকে সহজেই চিহ্নিত করতে পারবেন না (শাখাগুলির নামকরণ, সরানো, মুছতে পারে ...), যদিও git branch --contains <commit>এটি একটি শুরু start

  • শাখা এবং তালিকা শাখার তালিকা git branch --contains <commit>না দেওয়া পর্যন্ত আপনি প্রতিশ্রুতিবদ্ধ থেকে ফিরে যেতে পারেন ,featuredevelop
  • তুলনা করুন যে SHA1 কমিট /refs/heads/develop

যদি দুটি আইডির সাথে মিলে যায় তবে আপনি যেতে ভাল (এর অর্থ হবে featureশাখার উত্‍পত্তিটি হেডের শিরোনামে রয়েছে develop)।


6

জো ক্রাইসলারের কমান্ড-লাইন যাদু সহজ করা যেতে পারে। জো এর যুক্তি এখানে - সংক্ষিপ্ততার জন্য আমি cur_branchকমান্ড প্রতিস্থাপনের জায়গায় একটি প্যারামিটার `git rev-parse --abbrev-ref HEAD`দুটি সংস্করণে প্রবর্তন করেছি ; এটিকে এভাবে আরম্ভ করা যেতে পারে:

cur_branch=$(git rev-parse --abbrev-ref HEAD)

তারপরে, জোয়ের পাইপলাইনটি এখানে:

git show-branch -a           |
  grep '\*'                  | # we want only lines that contain an asterisk
  grep -v "$cur_branch"      | # but also don't contain the current branch
  head -n1                   | # and only the first such line
  sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
  sed 's/[\^~].*//'            # and with any relative refs (^, ~n) removed

অপেক্ষাকৃত সহজ awkকমান্ডে সেই পাঁচটি স্বতন্ত্র কমান্ড ফিল্টার হিসাবে আমরা একই জিনিস অর্জন করতে পারি :

git show-branch -a |
  awk -F'[]^~[]' '/\*/ && !/'"$cur_branch"'/ {print $2;exit}'  

এটি এইভাবে ভেঙে যায়:

-F'[]^~[]' 

এ ক্ষেত্রগুলির মধ্যে লাইন বিভক্ত ], ^, ~, এবং [অক্ষর।

/\*/                      

একটি নক্ষত্রযুক্ত লাইনগুলি সন্ধান করুন

&& !/'"$cur_branch"'/

... তবে বর্তমান শাখার নাম নয়

{ print $2;               

আপনি যখন এই জাতীয় একটি লাইন পান, তার দ্বিতীয় ক্ষেত্রটি মুদ্রণ করুন (এটি আমাদের ফিল্ড বিভাজক অক্ষরের প্রথম এবং দ্বিতীয় সংখ্যার মধ্যে অংশ)। সাধারণ শাখার নামগুলির জন্য, এটি বন্ধনীগুলির মধ্যে ঠিক কী হবে; আপেক্ষিক জাম্প সহ রেফের জন্য, এটি পরিবর্তনকারী ছাড়াই কেবল নাম হবে। সুতরাং আমাদের ক্ষেত্র বিভাজকের সেট উভয় sedকমান্ডের অভিপ্রায় পরিচালনা করে ।

  exit }

তারপরে তাত্ক্ষণিক প্রস্থান করুন। এর অর্থ এটি কেবল সর্বদা প্রথম মিলের লাইনে প্রক্রিয়াজাত হয়, সুতরাং আমাদের আউটপুটটি পাইপ করার দরকার নেই head -n 1


3
লক্ষ্য করুন যে কয়েকটি শাখাগুলি প্রচুর রেফের কারণে আউটপুট থেকে নিখোঁজ হতে পারে। পরিবর্তে তারা stderr এ সতর্কতা হিসাবে দেখানো হয়।
জিতরেক্স

5

এখানে মার্ক রিডের সমাধানের পাওয়ারশেল বাস্তবায়ন:

git show-branch -a | where-object { $_.Contains('*') -eq $true} | Where-object {$_.Contains($branchName) -ne $true } | select -first 1 | % {$_ -replace('.*\[(.*)\].*','$1')} | % { $_ -replace('[\^~].*','') }

5

আমি এই সমস্যাটি সমাধান করার জন্য এটি একটি ভাল উপায় বলছি না, তবে এটি আমার পক্ষে কার্যকর বলে মনে হয়।

git branch --contains $(cat .git/ORIG_HEAD) সমস্যাটি হ'ল কোনও ফাইলকে বিড়াল করা গিটের অভ্যন্তরীণ কাজের মধ্যে উঁকি দিচ্ছে সুতরাং এটি ফরওয়ার্ডস-সামঞ্জস্যপূর্ণ (বা পিছনের দিকে সামঞ্জস্যপূর্ণ) নয়।


3

পিঁপড়ের সাথে ক্রস প্ল্যাটফর্ম বাস্তবায়ন

    <exec executable="git" outputproperty="currentBranch">
        <arg value="rev-parse" />  
        <arg value="--abbrev-ref" />  
        <arg value="HEAD" />  
    </exec>

    <exec executable="git" outputproperty="showBranchOutput">
        <arg value="show-branch" />  
        <arg value="-a" />  
    </exec>

    <loadresource property="baseBranch">
      <propertyresource name="showBranchOutput"/>
          <filterchain>
            <linecontains>
              <contains value="*"/>
            </linecontains>
            <linecontains negate="true">
              <contains value="${currentBranch}"/>
            </linecontains>
            <headfilter lines="1"/>
            <tokenfilter>
                <replaceregex pattern=".*\[(.*)\].*" replace="\1"/>
                <replaceregex pattern="[\^~].*" replace=""/>
            </tokenfilter>
          </filterchain>
    </loadresource>

    <echo message="${currentBranch} ${baseBranch}" />

2

@ মার্ক রিড: আপনার যুক্ত করা উচিত যে প্রতিশ্রুতিবদ্ধ রেখায় কেবল একটি নক্ষত্র যুক্ত হওয়া উচিত নয়, একটি নক্ষত্র দিয়ে শুরু করা উচিত! অন্যথায় একটি নক্ষত্র রয়েছে এমন প্রতিবেদনগুলি মিলে যাওয়া লাইনেও অন্তর্ভুক্ত রয়েছে। সুতরাং এটি হওয়া উচিত:

git show-branch -a | awk -F'[]^~[]' '/^\*/ && !/'"$current_branch"'/ {print $2;exit}'

বা দীর্ঘ সংস্করণ:

git show-branch -a           |
  awk '^\*'                  | # we want only lines that contain an asterisk
  awk -v "$current_branch"   | # but also don't contain the current branch
  head -n1                   | # and only the first such line
  sed 's/.*\[\(.*\)\].*/\1/' | # really, just the part of the line between []
  sed 's/[\^~].*//'            # and with any relative refs (^, ~n) removed`

2
vbc=$(git rev-parse --abbrev-ref HEAD)
vbc_col=$(( $(git show-branch | grep '^[^\[]*\*' | head -1 | cut -d* -f1 | wc -c) - 1 )) 
swimming_lane_start_row=$(( $(git show-branch | grep -n "^[\-]*$" | cut -d: -f1) + 1 )) 
git show-branch | tail -n +$swimming_lane_start_row | grep -v "^[^\[]*\[$vbc" | grep "^.\{$vbc_col\}[^ ]" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

মার্ক রিডের উত্তরের মতো একই প্রান্তটি অর্জন করে তবে অনেক বেশি নিরাপদ পদ্ধতির ব্যবহার করে যা বেশ কয়েকটি দৃশ্যে খারাপ ব্যবহার করে না:

  1. অভিভাবক শাখার শেষ প্রতিশ্রুতি একত্রীকরণ, কলামটি শো করে - না*
  2. কমিট বার্তায় শাখার নাম রয়েছে
  3. প্রতিশ্রুতিবদ্ধ বার্তা রয়েছে *

0

আজকাল যে কেউ এই কাজটি করতে চাইছেন - অ্যাটলিশিয়ানদের সোর্স ট্রি অ্যাপ্লিকেশন আপনাকে কীভাবে আপনার শাখাগুলি একে অপরের সাথে সম্পর্কিত তার দুর্দান্ত দর্শন উপস্থাপন করে, যেমন তারা কোথায় শুরু হয়েছিল এবং তারা বর্তমানে কমিট ক্রমে কোথায় বসে (উদাহরণস্বরূপ শিরোনাম বা 4 টি পিছনে কমিট ইত্যাদি) etc. ।


0

যদি আপনি উত্স গাছ ব্যবহার করেন তবে আপনার প্রতিশ্রুতি বিবরণ> পিতামাতারা> দেখুন তবে কমিটের সংখ্যাগুলি আন্ডারলাইন করা হবে (লিঙ্কগুলি)


0

একটি বিকল্প: git rev-list master | grep "$(git rev-list HEAD)" | head -1

শেষ প্রতিশ্রুতি পান যে এটি আমার শাখা এবং master(বা আপনি যে শাখাটি নির্দিষ্ট করতে চান) উভয়ই


0

আমি যখন এমন কিছু করেছি তখন এটি আমার পক্ষে কাজ করে না develop > release-v1.0.0 > feature-foo, এটি পুরোপুরি বিকাশের পথে চলে যেত, মনে রাখবেন যে একটি রিবেস জড়িত ছিল তা নিশ্চিত নয় যে এটি আমার সমস্যাটিকে আরও জটিল করে তুলছে কিনা ...

নিম্নলিখিতটি আমার জন্য সঠিক প্রতিশ্রুতিবদ্ধ হ্যাশ দিয়েছে

git log --decorate \
  | grep 'commit' \
  | grep 'origin/' \
  | head -n 2 \
  | tail -n 1 \
  | awk '{ print $2 }' \
  | tr -d "\n"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.