Git repository unique id

前端 未结 5 775
别跟我提以往
别跟我提以往 2021-01-13 00:44

I need to find out if a commit belongs to a particular git repository.

The idea is to generate some unique id for every repository I need to test. Then I can compa

5条回答
  •  误落风尘
    2021-01-13 01:07

    Compare with Mercurial, where is checks mercurial/treediscovery.py (Mercurial repository identification):

    base = list(base)
    if base == [nullid]:
        if force:
            repo.ui.warn(_("warning: repository is unrelated\n"))
        else:
            raise util.Abort(_("repository is unrelated"))
    

    base variable store last common parts of two repositories.

    Git have same assumptions when emit warning: no common commits on fetch/push. I just didn't grep Git sources, that require time.

    By giving this idea of Mercurial push/pull checks we may assume that repositories are related if they have common roots. For mercurial this means that hashes from command:

    $ hg log -r "roots(all())"
    

    for both repositories must have non-empty interjection.

    You may not trick roots checking by carefully crafting repositories because building two repositories looks like these (with common parts but different roots):

    0 <--- SHA-256-XXX <--- SHA-256-YYY <--- SHA-256-ZZZ
    0 <--- SHA-256-YYY <--- SHA-256-ZZZ
    

    impossible because that mean you reverse SHA-256 as each subsequent hash depends on previous values. That is true both for Mercurial and Git.

    Corresponding command to see roots in Git is:

    $ git log --format=oneline --all --max-parents=0
    

    You can toy yourself with:

    bash# md git
    /home/user/tmp/git
    
    bash# md one
    /home/user/tmp/git/one
    
    bash# git init
    Initialized empty Git repository in /home/user/tmp/git/one/.git/
    
    bash# echo x1 > x1
    bash# git add x1
    bash# git ci -m x1
    [master (root-commit) 1208fb0] x1
    
    bash# echo x2 > x2
    bash# git add x2
    bash# git ci -m x2
    [master 1c3fe86] x2
    
    bash# cd ..
    
    bash# md two
    /home/user/tmp/git/two
    
    bash# git init
    Initialized empty Git repository in /home/user/tmp/git/two/.git/
    
    bash# echo y1 > y1
    bash# git add y1
    bash# git ci -m y1
    [master (root-commit) ff56a8e] y1
    
    bash# echo y2 > y2
    bash# git add y2
    bash# git ci -m y2
    [master 18adff5] y2
    
    bash# git fetch ../one/
    warning: no common commits
    remote: Counting objects: 6, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 6 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (6/6), done.
    From ../one
     * branch            HEAD       -> FETCH_HEAD
    
    bash# git co --orphan one
    Switched to a new branch 'one'
    
    bash# git merge FETCH_HEAD
    
    bash# git log --format=oneline --all
    18adff541c7ce9f1a1f2be2804d6d0e5792ff086 y2
    ff56a8e7e9145d2b1b5a760bbc9b12451927ab0c y1
    1c3fe8665851e89d37f49633cd2478900217b91c x2
    1208fb0f721005207c6afe6a549a9ed0dcc5b0a8 x1
    
    bash# git log --format=oneline --all --max-parents=0
    ff56a8e7e9145d2b1b5a760bbc9b12451927ab0c y1
    1208fb0f721005207c6afe6a549a9ed0dcc5b0a8 x1
    
    bash# git log --all --graph
    
    * commit 18adff541c7ce9f1a1f2be2804d6d0e5792ff086
    |     y2
    |  
    * commit ff56a8e7e9145d2b1b5a760bbc9b12451927ab0c
          y1
    
    * commit 1c3fe8665851e89d37f49633cd2478900217b91c
    |     x2
    |  
    * commit 1208fb0f721005207c6afe6a549a9ed0dcc5b0a8
          x1
    

    NOTE Git allow partial checkout. I didn't check this case for --max-parents=0.

提交回复
热议问题