Git bisect与合并的提交 [英] Git bisect with merged commits

查看:84
本文介绍了Git bisect与合并的提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的历史记录如下:

* 3830e61 Add data escaping.              (Bad)
* 0f5e148 Improve function for getting page template.
*   aaf8dc5 Merge branch 'navigation'
|\
| * 3e667f8 Add icons.
| * 43a07b1 Add menu styles.              (Breaks)
| * 107ca95 Add Responsive Nav.           (Good)
* | ea3d736 Add ‘Admin’ notice.
* | 17ca0bb Update placeholder text.
|/
* f52cc34 Add featured image.
* 2abd954 Style placeholders.

我正在尝试学习更多内容和git bisect,但是在这段历史上遇到了麻烦.我知道107ca95是好的,而3830e61是不好的.当我运行git bisect时,将忽略107ca95..3e667f8提交.我碰巧知道43a07b1是引入了回归的提交,但从未对其进行评估.

I am trying to learn more and git bisect, but am having trouble with this history. I know that 107ca95 is good and 3830e61 is bad. When I run a git bisect, commits 107ca95..3e667f8 are ignored. I happen to know that 43a07b1 is the commit that introduced a regression, but it is never evaluated.

这大致就是我所做的:

git checkout master
git bisect start
git bisect bad
git bisect good 107ca95
git bisect bad (multiple times)

无论我做什么,都不会签出107ca95..3e667f8进行测试.

No matter what I do, 107ca95..3e667f8 are never checked out to be tested.

有什么办法可以使我平分二等分期间的历史来测试那些提交?我知道我可以使用交互式rebase来整理历史记录,但是我不想这样做.

Is there any way that I can essentially "flatten" the history during the bisect to test those commits? I know I can use an interactive rebase to flatten the history, but I do not want to have to do that.

推荐答案

这是一个非常古老但尚未得到解答的问题.我决定进行调查,结果发现我可以证明Git的行为不同于问题的含义. 一种解释是Git改进了bisect算法,或者发问者在标记提交时犯了一个错误.

This is a very old but unanswered question. I decided to investigate, and found that I could show that the behavior of Git is different to what the question says it is. One explanation is that Git improved the algorithm for bisect, or that the questioner made a mistake in marking commits.

我正在尝试学习更多和git bisect,但是在这段历史上遇到了麻烦.我知道107ca95是好的,而3830e61是不好的.当我运行git bisect时,将忽略提交107ca95..3e667f8.我碰巧知道43a07b1是引入了回归的提交,但是从未评估.

I am trying to learn more and git bisect, but am having trouble with this history. I know that 107ca95 is good and 3830e61 is bad. When I run a git bisect, commits 107ca95..3e667f8 are ignored. I happen to know that 43a07b1 is the commit that introduced a regression, but it is never evaluated.

我写了一些代码来检查它是否被评估.我的测试表明它得到了评估.运行以下代码,并验证是否出现带有消息Add menu styles.的提交.

I wrote some code to check whether it is evaluated or not. My test shows that it is evaluated. Run the code below and verify that a commit with message Add menu styles. appears.

更多评论:

  • 提交107ca95..3e667f8被忽略":请注意,由于git已经知道它是好的,因此不会评估您标记为良好"的提交.
  • 请阅读这篇文章由克里斯蒂安·库德(Christian Couder)撰写.另外,检查合并基础"部分也可能是相关的.
  • 如上所述,问题肯定是使用的版本与我使用的版本不同(问题来自2013年,Git 2.11来自2016年.)
  • "commits 107ca95..3e667f8 are ignored": Please note, that the commit you marked as "good" will not be evaluated because git already knows it to be good.
  • Please read the section "Bisection Algorithm" in this article by Christian Couder. Also the section "Checking merge bases" might be relevant.
  • As mentioned above, the question was certainly using a different version then the one I used (Question is from 2013, Git 2.11 is from 2016).
  • 请注意,第一个添加管理员通知"已选中(第4行),因为它提供了最多的信息. (请阅读上述文章中的检查合并基础".)
  • 从那时起,它会将线性历史一分为二.

# bad: [d7761d6f146eaca1d886f793ced4315539326866] Add data escaping. (Bad)
# good: [f555d9063a25a20a6ec7c3b0c0504ffe0a997e98] Add Responsive Nav. (Good)
git bisect start 'd7761d6f146eaca1d886f793ced4315539326866' 'f555d9063a25a20a6ec7c3b0c0504ffe0a997e98'
# good: [1b3b7f4952732fec0c68a37d5f313d6f4219e4ae] Add ‘Admin’ notice. (Good)
git bisect good 1b3b7f4952732fec0c68a37d5f313d6f4219e4ae
# bad: [f9a65fe9e6cde4358e5b8ef7569332abfb07675e] Add icons. (Bad)
git bisect bad f9a65fe9e6cde4358e5b8ef7569332abfb07675e
# bad: [165b8a6e5137c40ce8b90911e59d7ec8eec30f46] Add menu styles. (Bad)
git bisect bad 165b8a6e5137c40ce8b90911e59d7ec8eec30f46
# first bad commit: [165b8a6e5137c40ce8b90911e59d7ec8eec30f46] Add menu styles. (Bad)

代码

使用Git 2.11.0在 Python 3 中运行. 运行命令:python3 script.py

Code

Run in Python 3, with Git 2.11.0. Command to run: python3 script.py

""" The following code creates a git repository in '/tmp/git-repo' and populates
it with the following commit graph. Each commit has a test.sh which can be used
as input to a git-bisect-run.

The code then tries to find the breaking change automatically.
And prints out the git bisect log.

Written in response to http://stackoverflow.com/questions/17267816/git-bisect-with-merged-commits
to test the claim that '107ca95..3e667f8 are never checked out'.

Needs Python 3!
"""


from itertools import chain
import os.path
import os
import sh

repo = {
0x3830e61:  {'message': "Add data escaping.", 'parents': [    0x0f5e148    ], 'test': False} , # Last:    (Bad)
0x0f5e148: {'message': "Improve function for getting page template.", 'parents': [ 0xaaf8dc5], 'test': False},
0xaaf8dc5: {'message': "Merge branch 'navigation'", 'parents': [ 0x3e667f8, 0xea3d736], 'test': False},
    0x3e667f8: {'message': "Add icons.", 'parents': [  0x43a07b1], 'test': False},
    0x43a07b1: {'message': "Add menu styles.", 'parents': [    0x107ca95], 'test': False}  , # First:       (Breaks)
    0x107ca95: {'message': "Add Responsive Nav.", 'parents': [   0xf52cc34], 'test': True}, # First:        (Good)
  0xea3d736: {'message': "Add ‘Admin’ notice.", 'parents': [ 0x17ca0bb], 'test': True},
  0x17ca0bb: {'message': "Update placeholder text.", 'parents': [  0xf52cc34], 'test': True},
0xf52cc34: {'message': "Add featured image.", 'parents': [  0x2abd954], 'test': True},
0x2abd954: {'message': "Style placeholders.", 'parents': [], 'test': True},
}

bad = 0x3830e61
good = 0x107ca95


def generate_queue(_dag, parents):
    for prev in parents:
        yield prev
        yield from generate_queue(_dag, _dag[prev]['parents'])

def make_queue(_dag, inits):
    """ Converts repo (a DAG) into a queue """
    q = list(generate_queue(_dag, inits))
    q.reverse()
    seen = set()
    r = [x for x in q if not (x in seen or seen.add(x))]
    return r

if __name__ == '__main__':
    pwd = '/tmp/git-repo'
    sh.rm('-r', pwd)
    sh.mkdir('-p', pwd)
    g = sh.git.bake(_cwd=pwd)
    g.init()

    parents = set(chain.from_iterable((repo[c]['parents'] for c in repo)))

    commits = set(repo)
    inits = list(commits - parents)
    queue = make_queue(repo, inits)

    assert len(queue) == len(repo), "queue {} vs repo {}".format(len(queue), len(repo))

    commit_ids = {}
    # Create commits
    for c in queue:
        # Set up repo
        parents = repo[c]['parents']
        if len(parents) > 0:
            g.checkout(commit_ids[parents[0]])
        if len(parents) > 1:
            if len(parents) > 2: raise NotImplementedError('Octopus merges not support yet.')
            g.merge('--no-commit', '-s', 'ours', commit_ids[parents[1]])  # just force to use 'ours' strategy.

        # Make changes
        with open(os.path.join(pwd, 'test.sh'), 'w') as f:
            f.write('exit {:d}\n'.format(0 if repo[c]['test'] else 1))
        os.chmod(os.path.join(pwd, 'test.sh'), 0o0755)
        with open(os.path.join(pwd, 'message'), 'w') as f:
            f.write(repo[c]['message'])
        g.add('test.sh', 'message')
        g.commit('-m', '{msg} ({test})'.format(msg=repo[c]['message'], test='Good' if repo[c]['test'] else 'Bad'))
        commit_ids[c] = g('rev-parse', 'HEAD').strip()

    # Run git-bisect
    g.bisect('start', commit_ids[bad], commit_ids[good])
    g.bisect('run', './test.sh')
    print(g.bisect('log'))

这篇关于Git bisect与合并的提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆