プログラムで2つのブランチの共通の祖先を見つける方法

アビシェク・ソニ:

私は自分のプロジェクトをと統合したプロジェクトに取り組んでいgitます。統合のために、私はgo-gitライブラリを使用しています。私の質問は、プログラムで2つのブランチの共通の祖先をどのように見つけることができるかです。この機能を実装したい。go-git他の囲碁ライブラリはそのような機能を提供していないように見えます。

orirawlings:

go-gitこれは、以下の動作を模倣した小さなプログラムです。git merge-base --all

package main

import (
    "fmt"
    "os"

    "gopkg.in/src-d/go-git.v4"
    . "gopkg.in/src-d/go-git.v4/_examples"
    "gopkg.in/src-d/go-git.v4/plumbing"
    "gopkg.in/src-d/go-git.v4/plumbing/object"
    "gopkg.in/src-d/go-git.v4/plumbing/storer"
)

// store h in set, s, handling nil s if necessary. Return new set.
func store(s map[plumbing.Hash]bool, h plumbing.Hash) map[plumbing.Hash]bool {
    if s == nil {
        s = make(map[plumbing.Hash]bool)
    }
    s[h] = true
    return s
}

// mergeBase finds best common ancestors between two commits to use in a
// three-way merge. One common ancestor is better than another common ancestor
// if the latter is an ancestor of the former. A common ancestor that does not
// have any better common ancestor is a best common ancestor, i.e. a merge base.
// Note that there can be more than one merge base for a pair of commits.
func mergeBase(s storer.EncodedObjectStorer, a, b plumbing.Hash) ([]plumbing.Hash, error) {
    commitA, err := object.GetCommit(s, a)
    if err != nil {
        return nil, err
    }

    commitB, err := object.GetCommit(s, b)
    if err != nil {
        return nil, err
    }

    // Mapping of direct descendants of each commit we visit
    desc := make(map[plumbing.Hash]map[plumbing.Hash]bool)

    // Set of commits reachable from a
    reachableFromA := make(map[plumbing.Hash]bool)

    // Walk commits reachable from A
    err = object.NewCommitPreorderIter(commitA, nil, nil).ForEach(func(c *object.Commit) error {
        reachableFromA[c.Hash] = true
        for _, h := range c.ParentHashes {
            desc[h] = store(desc[h], c.Hash)
        }
        return nil
    })
    if err != nil {
        return nil, err
    }

    // Set of common commits between a and b
    common := make(map[plumbing.Hash]bool)

    // Walk commits reachable from B
    err = object.NewCommitPreorderIter(commitB, nil, nil).ForEach(func(c *object.Commit) error {
        if reachableFromA[c.Hash] {
            common[c.Hash] = true
        }
        for _, h := range c.ParentHashes {
            desc[h] = store(desc[h], c.Hash)
        }
        return nil
    })
    if err != nil {
        return nil, err
    }

    best := make(map[plumbing.Hash]bool)

    // Trim down the set of common commits to only those that are best
    for h := range common {
        best[h] = true
        for child := range desc[h] {
            if common[child] {
                // there is a descendant to h that is common to both a and b. h is not in best.
                delete(best, h)
                break
            }
        }
    }

    var result []plumbing.Hash
    for h := range best {
        result = append(result, h)
    }
    return result, nil
}

// Open an existing repository in a specific folder.
func main() {
    CheckArgs("<path> <commitA> <commitB>")
    path := os.Args[1]
    a := plumbing.NewHash(os.Args[2])
    b := plumbing.NewHash(os.Args[3])

    r, err := git.PlainOpen(path)
    CheckIfError(err)

    bases, err := mergeBase(r.Storer, a, b)
    CheckIfError(err)

    for _, b := range bases {
        fmt.Println(b)
    }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

3つ以上のブランチの共通の祖先を見つける

分類Dev

git:すでにマージされている2つのブランチの共通の祖先を見つけるにはどうすればよいですか?

分類Dev

2つの配列で共通の要素を見つけるためのJavascriptプログラム

分類Dev

2つのブランチをプログラムで統合する方法

分類Dev

tfsでブランチのタイムスタンプを見つける方法

分類Dev

2つの数の積を見つけるプログラム

分類Dev

共通の祖先を含む2つのブランチ間で異なるコミットを表示するgitログ

分類Dev

Git:2つのブランチの最新の共通祖先を検索します

分類Dev

Git:2つのブランチの最新の共通祖先を検索します

分類Dev

Git:2つのブランチの最新の共通祖先を検索します

分類Dev

プログラムのレンダリングAPIを見つける方法は?

分類Dev

プログラムでAndroidのドット抜けを見つける方法

分類Dev

プロセスの祖先チェーンを見つける方法は?

分類Dev

2の補数を見つけるCプログラム

分類Dev

マシン上のコアの数をプログラムで見つける

分類Dev

プログラムでRの現在のバージョンを見つける

分類Dev

gitでブランチの起源を見つける方法は?

分類Dev

毎月のプログラムで日を見つける

分類Dev

PrologでGcdを見つけるためのプログラム

分類Dev

2つのリストで共通の要素を見つける方法は?プロローグ

分類Dev

私のプログラムで「constchar * + int」式を見つける方法

分類Dev

プログラムでViewControllerの高さを見つける方法は?

分類Dev

Javaプログラムで文字列内の母音を見つける方法

分類Dev

2つのブランチをいくつかの同様のコミットでマージし、共通の祖先を持たない方法は?

分類Dev

「プログラムから開く」リストでプログラムの場所を見つける方法は?

分類Dev

iOS8でゲームセンターの友達をプログラムで見つける方法

分類Dev

XQueryで2つのノードの最も低い共通の祖先を見つける方法は?

分類Dev

android sqliteでテーブルの主キーをプログラムで見つける方法は?

分類Dev

FlutterDriverを使用してプログラムでiOSの戻るボタンを見つける方法

Related 関連記事

  1. 1

    3つ以上のブランチの共通の祖先を見つける

  2. 2

    git:すでにマージされている2つのブランチの共通の祖先を見つけるにはどうすればよいですか?

  3. 3

    2つの配列で共通の要素を見つけるためのJavascriptプログラム

  4. 4

    2つのブランチをプログラムで統合する方法

  5. 5

    tfsでブランチのタイムスタンプを見つける方法

  6. 6

    2つの数の積を見つけるプログラム

  7. 7

    共通の祖先を含む2つのブランチ間で異なるコミットを表示するgitログ

  8. 8

    Git:2つのブランチの最新の共通祖先を検索します

  9. 9

    Git:2つのブランチの最新の共通祖先を検索します

  10. 10

    Git:2つのブランチの最新の共通祖先を検索します

  11. 11

    プログラムのレンダリングAPIを見つける方法は?

  12. 12

    プログラムでAndroidのドット抜けを見つける方法

  13. 13

    プロセスの祖先チェーンを見つける方法は?

  14. 14

    2の補数を見つけるCプログラム

  15. 15

    マシン上のコアの数をプログラムで見つける

  16. 16

    プログラムでRの現在のバージョンを見つける

  17. 17

    gitでブランチの起源を見つける方法は?

  18. 18

    毎月のプログラムで日を見つける

  19. 19

    PrologでGcdを見つけるためのプログラム

  20. 20

    2つのリストで共通の要素を見つける方法は?プロローグ

  21. 21

    私のプログラムで「constchar * + int」式を見つける方法

  22. 22

    プログラムでViewControllerの高さを見つける方法は?

  23. 23

    Javaプログラムで文字列内の母音を見つける方法

  24. 24

    2つのブランチをいくつかの同様のコミットでマージし、共通の祖先を持たない方法は?

  25. 25

    「プログラムから開く」リストでプログラムの場所を見つける方法は?

  26. 26

    iOS8でゲームセンターの友達をプログラムで見つける方法

  27. 27

    XQueryで2つのノードの最も低い共通の祖先を見つける方法は?

  28. 28

    android sqliteでテーブルの主キーをプログラムで見つける方法は?

  29. 29

    FlutterDriverを使用してプログラムでiOSの戻るボタンを見つける方法

ホットタグ

アーカイブ