我如何产生每一个可能的git-status?

时间:2014-04-01 17:35:16

标签: git jgit

背景

我们正在使用git进行我正在处理的Web应用程序中的源代码管理。有一个编辑器,所以还有一个git的web界面。

我们的一个使用案例是人们也可以从命令行管理他们的git存储库,因此Web界面需要能够以某种方式处理它找到存储库的任何奇怪状态。

问题:

对于测试,在每个可能的状态下获取带有文件的git存储库会很棒,因此我可以验证是否处理了所有可能的条件。阅读"man git-status(1)"我计算了文件可能存在的24种状态(不计算被忽略)。

我只想出了如何创建其中的17种状态。

以下是我不知道如何重现的状态的XY代码(参见git-status)。

D           M    deleted from index
C        [ MD]   copied in index
D           D    unmerged, both deleted
A           U    unmerged, added by us
U           A    unmerged, added by them

有一个带有ruby脚本的gist on github创建了我已经知道如何重现的每个状态,我很乐意将其完整。

2 个答案:

答案 0 :(得分:2)

根据来源,它的价值是什么,今天没有办法让“复制在索引中”:

wt-status.c:            status = d->index_status;
wt-status.c:            if (!d->index_status)
wt-status.c:                    d->index_status = p->status;
wt-status.c:                    d->index_status = DIFF_STATUS_UNMERGED;
wt-status.c:                    d->index_status = DIFF_STATUS_ADDED;
wt-status.c:            if (!d->index_status ||
wt-status.c:                d->index_status == DIFF_STATUS_UNMERGED)
wt-status.c:    if (d->index_status)
wt-status.c:            color_fprintf(s->fp, color(WT_STATUS_UPDATED, s), "%c", 
wt-status.h:    int index_status;

(其中index_status是为第一列打印的字母)。因此,直接分配可以将其设置为UA,而p->status的副本分配可以将其设置为p->status设置的任何内容。这最终是通过这个位代码来控制的:

static void wt_status_collect_changes_index(struct wt_status *s)
{
        struct rev_info rev;
        struct setup_revision_opt opt;

        init_revisions(&rev, NULL);
        memset(&opt, 0, sizeof(opt));
        opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
        setup_revisions(0, NULL, &rev, &opt);

        if (s->ignore_submodule_arg) {
                DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
        }

        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = wt_status_collect_updated_cb;
        rev.diffopt.format_callback_data = s;
        rev.diffopt.detect_rename = 1;
        rev.diffopt.rename_limit = 200;
        rev.diffopt.break_opt = 0;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_index(&rev, 1);
}

这里的差异选项如上所示:detect_rename设置为DIFF_DETECT_RENAME(1 - 这应该使用#define,真的),限制为200.如果{ {1}}已设置为detect_rename(2),您可以获得州DIFF_DETECT_COPY

我通过修改C(见下文)测试了这个,然后对另一个文件大惊小怪:

wt-status.c

请注意,仍然没有设置$ git status --short M wt-status.c $ git mv zlib.c zzy.c; cp zzy.c zzz.c; git add zzz.c; git status --short M wt-status.c R zlib.c -> zzy.c A zzz.c $ ./git-status --short M wt-status.c C zlib.c -> zzy.c R zlib.c -> zzz.c 的等效值,因此您必须至少有一个重命名才能获得复制状态:

--find-copies-harder

要做到这一点,我还必须添加另一个$ git mv zzy.c zlib.c; ./git-status --short M wt-status.c A zzz.c

DIFF_OPT_SET

我现在停止了,现在已经足够了: - )

克里斯

答案 1 :(得分:2)

通过将这个问题发布到git邮件列表,我得到了七个代码中的四个的答案,由@torek进行的调查现在已经完全回答了这个问题,尽管我不太清楚如何在stackoverflow中反映出来。

您可以阅读git mailing list discussion了解详细信息,但简短的回答是,使用@torek提供的信息,git命令行工具的普通用户无法访问我无法重现的任何状态组合。