当多个作者使用版本控制时,如何跟踪库的构建计数? [英] How do you track the build count of your library when there are multiple authors using version control?

查看:144
本文介绍了当多个作者使用版本控制时,如何跟踪库的构建计数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道这是否是人们常见的事情,但我个人总是跟踪我编写代码的次数。也就是说,我调用 make 的次数以及构建成功的次数。



我的目前的解决方案



我有一个简单的代码,将一个文件作为参数,打开它,增加内部数字并覆盖它。这段代码被编译,首先调用 make



紧接着,。调用/ increase_build build.txt 会增加我调用 make 来构建库的次数。



然后,编译代码并创建lib文件(使用 ar cq ... )。之后,调用 ./ increase_build libbuild.txt ,以增加成功构建的数量。最后,这些测试是建立的。



这是一个我的Makefiles的例子。



为什么我会关注



工作得很好,直到我开始使用版本控制。似乎没有问题:我是我自己的库的唯一作者,我一个接一个地添加了功能。



尽管有一天,我正在测试分支和合并(我在工作中使用Git和svn),所以我在分支中添加了一个功能,并在主服务器中更改了一些内容,然后合并了这两个功能。现在构建计数文件有不同的值。



问题



问题在于,的分支,构建计数为100.然后我在分支中写入内容,构建计数达到110.我在主分支中编写了一些内容,构建计数达到了120.当我合并这两个时,我看到一个是110和1是120(这是一个冲突的方式)。正确的解决方案是将版本设置为130.然而,我不能(阅读我不想)回到提交分支的地方起飞,发现它是100,所以我计算100+(110-100)+(120-100)= 130!我想这是自动的



问题



那问题很明显:我该怎么做?当我使用版本控制时,如何跟踪我的构建计数(不提交数量!)?我不想要一个基于版本控制功能的答案,因为如果我更改版本控制系统,问题会重新出现。



我可以工作就是在构建计数文件中为每个构建添加一行,这与数据和时间有关。然后内部版本号将是构建计数文件中的行数。另外,除非我在两个分支上获得两个完全相同的时间,那么合并这些文件将只是两者的结合。



我想知道有没有更好的解决方案呢?我想要什么(构建计数)甚至值得付出努力?

如果你想知道为什么我在构建的数量和成功的构建数量上都这样做,那只是个人的事情。我喜欢看我在编写代码时犯的小错别字和错误的重建程度。



编辑:我用C和C ++编程,所以一个解决方案或者适用于我。

解决方案

我将发布并接受我自己的想法的实现答案,因为它似乎是最实际的。



因此,解决方案如下:


  • 使用每个构建,向包含以下数据的构建文件添加一行:


    • 日期

    • 时间

    • 随机数


    • 每次合并时, li>
    • 构建的数量是构建文件中的总行数。



    构建文件需要是唯一的。日期和时间使得这一点非常独特。两个人不太可能同时在自己的分支上发布构建。但是,它可能发生。因此,生成一个随机数并加入以减少这个机会。

    虽然有一个问题。如果您使用 time(NULL) srand 种下,那么由于两个构建假设同时生成,也可能碰巧是一样的。因此,随机数发生器可以使用不同的数字进行播种,例如 clock()的毫秒部分gettimeofday()。即使不是随机生成的,这些数字本身也可以被放置,而不是随机数。



    在仍然有两行结束的情况下,我将应用鸵鸟算法

    更新:



    我实现了它,一切正常。最后,我使用 clock_gettime(CLOCK_MONOTONIC,...)并将通过此函数获得的纳秒显示为随机数。我没有使用 clock()的原因是由于程序很短,运行时间比 clock() code>因此我一直得到0。



    更新:

    这是我写的最后一段代码(有些部分从别的地方偷走了!)。在某些平台上,您可能需要 -lrt

      / * 
    *该程序是免费软件:您可以根据条款重新发布和/或修改
    * it由自由软件基金会
    *发行的GNU通用公共许可证,或许可证的第3版,或任何更新版本的
    *(可选)。
    *
    *这个程序是分发的,希望它有用,
    *但没有任何保证;甚至没有隐含的保证
    *的适销性或特定用途的适用性。有关更多详细信息,请参阅
    * GNU通用公共许可证。
    *
    *您应该收到GNU通用公共许可证
    *的副本以及此程序。如果没有,请参阅< http://www.gnu.org/licenses/> ;.
    * /

    #include< time.h>
    #include< stdio.h>
    #include< stdlib.h>

    #ifdef _WIN32
    #include< windows.h>

    struct timespec
    {
    long tv_sec;
    long tv_nsec;
    };

    / *注意:我从互联网复制粘贴(https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows/5404467#5404467)
    *我调整它返回纳秒而不是微秒
    *这比完全找到tv_nsec要完整得多,但我会保留它以备将来使用。 * /
    LARGE_INTEGER getFILETIMEoffset(void)
    {
    SYSTEMTIME s;
    FILETIME f;
    LARGE_INTEGER t;

    s.wYear = 1970;
    s.wMonth = 1;
    s.wDay = 1;
    s.wHour = 0;
    s.wMinute = 0;
    s.wSecond = 0;
    s.wMilliseconds = 0;
    SystemTimeToFileTime(& s,& f);
    t.QuadPart = f.dwHighDateTime;
    t.QuadPart<< = 32;
    t.QuadPart | = f.dwLowDateTime;
    return t;
    }

    int clock_gettime(int X,struct timespec * tv)
    {
    LARGE_INTEGER t;
    FILETIME f;
    双微秒;
    static LARGE_INTEGER offset;
    static double frequencyToNanoseconds;
    static int initialized = 0;
    static BOOL usePerformanceCounter = 0;

    if(!initialized)
    {
    LARGE_INTEGER performanceFrequency;
    初始化= 1;
    usePerformanceCounter = QueryPerformanceFrequency(& performanceFrequency);
    if(usePerformanceCounter)
    {
    QueryPerformanceCounter(& offset);
    frequencyToNanoseconds =(double)performanceFrequency.QuadPart / 1000000000.0;
    }
    else
    {
    offset = getFILETIMEoffset();
    frequencyToNanoseconds = 0.010;


    if(usePerformanceCounter)
    QueryPerformanceCounter(& t);
    else
    {
    GetSystemTimeAsFileTime(& f);
    t.QuadPart = f.dwHighDateTime;
    t.QuadPart<< = 32;
    t.QuadPart | = f.dwLowDateTime;
    }

    t.QuadPart - = offset.QuadPart;
    microseconds =(double)t.QuadPart / frequencyToNanoseconds;
    t.QuadPart =微秒;
    tv-> tv_sec = t.QuadPart / 1000000000;
    tv-> tv_nsec = t.QuadPart%1000000000;
    返回0;
    }

    #ifndef CLOCK_MONOTONIC
    #define CLOCK_MONOTONIC 0 / *不会使用* /
    #endif
    #endif

    int main(int argc,char ** argv)
    {
    time_t now_sec;
    struct tm * now;
    FILE * bout;
    struct timespec now_clk;
    if(argc <2)
    {
    printf(Usage:%s build_file_name\\\
    \\\
    ,argv [0]);;
    return EXIT_FAILURE;
    }
    bout = fopen(argv [1],a);
    if(!bout)
    {
    printf(无法打开文件:%s\\\
    \\\
    ,argv [1]);
    return EXIT_FAILURE;
    }
    时间(& now_sec);
    now = gmtime(& now_sec);
    fprintf(回合,%02d /%02d /%04d%02d:%02d:%02d,now-> tm_mday,now-> tm_mon + 1,now-> tm_year + 1900,now - > tm_hour,now-> tm_min,now-> tm_sec);
    clock_gettime(CLOCK_MONOTONIC,& now_clk);
    fprintf(bout,%ld\\\
    ,now_clk.tv_nsec);
    返回EXIT_SUCCESS;
    }

    希望这会对某人有所帮助。



    更新



    经过9个月的使用后,我可以说这非常有用。一些观察结果是:


    • 在Windows上,执行 clock_gettime 是相当小的,一半的时间具有相同的价值。尽管如此,它仍然使得它更加随机。

    • 在Linux上,最后一个元素确实是非常随机的。

    • 做一个构建提交只是为了获取构建文件中的行,因此我可以合并。但是,这可以通过 git stash 避免。

    • 合并时几乎总是会导致冲突,但对于解决它(只需从两个文件的行中删除diff标记)。

    • wc -l <​​/ code> 是您的朋友。


    I don't know if this is something common for people to do or not, but I personally always keep track of the number of times I built my code. That is, both the number of times I called make and the number of times the build was successful.

    My current solution

    I have a simple code that takes a file as parameter, opens it, increments the number inside and overwrites it. This code is compiled, first thing when make is called.

    Immediately after, ./increase_build build.txt is called which increments the number of times I called make to build the library.

    Then, the code is compiled and the lib file is made (with ar cq ...). After that, ./increase_build libbuild.txt is called that increments the number of successful builds. Finally the tests are built.

    This is an example of one of my Makefiles.

    Why I got concerned

    This always worked fine, until I started using version control. There seemed like there is no problem: I am the sole author of my own libraries and I add features one by one.

    One day though, I was testing branching and merging (I use git for myself and svn at work), so I added one feature in a branch and changed something in master and I merged the two. Now the build count files have different values.

    The problem

    The problem is, let's say at the time of branch, the build count is 100. Then I write something in branch and the build count gets to 110. I write something in master branch and the build count gets to 120. When I merge the two, I see one is 110 and one is 120 (which is a conflict by the way). The correct solution would be to set the build to 130.

    However, I can't (read I don't want to) go back to the commit where the branch took off and find that it was 100 so I compute 100+(110-100)+(120-100) = 130! I want this to be automatic

    The question

    Well the question is obvious: How do I do this? How do I keep track of my build count (not commit count!) when I'm working with version control? I don't want an answer that is based on a feature in the version control, because the problem arises anew if I change version control system.

    What I though could work was to add one line in the build count file for every build, something say with data and time. Then the build number would be the number of lines in the build count files. Also, unless I get two builds on two branches that were done the EXACT same time then merging the files would be just the union of the two.

    I wonder though, are there any better solutions to this? Is what I want (build counts) even worth the effort?

    P.S. If you are wondering why I do it with both the number of builds and the number of successful builds, that's just something personal. I like to see how much rebuild I get for small typos and errors I make when I code.

    Edit: I program in C and C++, so a solution in either works for me.

    解决方案

    I'm going to post and accept the implementation of my own idea as the answer, as it seems to be the most practical.

    So here's the solution:

    • With every build, add one line to the build file containing the following data:
      • Date
      • Time
      • A random number
    • With every merge, keep lines from both build files
    • The number of builds is the total number of lines in the build file.

    Each line of the build file needs to be unique. The date and time make that very nearly unique. It is very unlikely that two people issue a build on their own branch at the same time. However, it may happen. Therefore, a random number is generated and added to decrease that chance.

    There is one problem though. If you seed srand with time(NULL), then since both builds are supposedly at the same time, the generated number could also happen to be the same. Therefore, the random number generator could be seeded with a different number such as clock() or the milliseconds part of gettimeofday(). Even if not randomly generated, those numbers themselves could be put instead of a random number.

    In the case where still two lines ended up the same, I'll apply the ostrich algorithm.

    Update:

    I implemented it and everything works fine. Finally, I used clock_gettime(CLOCK_MONOTONIC, ...) and printed the nanoseconds obtained by this function as the random number. The reason I didn't use clock() was that since the program was quite short, it ran less than the resolution of clock() and therefore I kept getting 0s.

    Update:

    Here is the final code I wrote (with some parts of it stolen from somewhere else!). You may need -lrt on some platforms.

    /*
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #ifdef _WIN32
    #include <windows.h>
    
    struct timespec
    {
        long tv_sec;
        long tv_nsec;
    };
    
    /* Note: I copy-pasted this from internet (https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows/5404467#5404467)
     * I tweaked it to return nanoseconds instead of microseconds
     * It is much more complete than just finding tv_nsec, but I'm keeping it for possible future use. */
    LARGE_INTEGER getFILETIMEoffset(void)
    {
        SYSTEMTIME s;
        FILETIME f;
        LARGE_INTEGER t;
    
        s.wYear = 1970;
        s.wMonth = 1;
        s.wDay = 1;
        s.wHour = 0;
        s.wMinute = 0;
        s.wSecond = 0;
        s.wMilliseconds = 0;
        SystemTimeToFileTime(&s, &f);
        t.QuadPart = f.dwHighDateTime;
        t.QuadPart <<= 32;
        t.QuadPart |= f.dwLowDateTime;
        return t;
    }
    
    int clock_gettime(int X, struct timespec *tv)
    {
        LARGE_INTEGER t;
        FILETIME f;
        double microseconds;
        static LARGE_INTEGER offset;
        static double frequencyToNanoseconds;
        static int initialized = 0;
        static BOOL usePerformanceCounter = 0;
    
        if (!initialized)
        {
            LARGE_INTEGER performanceFrequency;
            initialized = 1;
            usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
            if (usePerformanceCounter)
            {
                QueryPerformanceCounter(&offset);
                frequencyToNanoseconds = (double)performanceFrequency.QuadPart/1000000000.0;
            }
            else
            {
                offset = getFILETIMEoffset();
                frequencyToNanoseconds = 0.010;
            }
        }
        if (usePerformanceCounter)
            QueryPerformanceCounter(&t);
        else
        {
            GetSystemTimeAsFileTime(&f);
            t.QuadPart = f.dwHighDateTime;
            t.QuadPart <<= 32;
            t.QuadPart |= f.dwLowDateTime;
        }
    
        t.QuadPart -= offset.QuadPart;
        microseconds = (double)t.QuadPart/frequencyToNanoseconds;
        t.QuadPart = microseconds;
        tv->tv_sec = t.QuadPart/1000000000;
        tv->tv_nsec = t.QuadPart%1000000000;
        return 0;
    }
    
    #ifndef CLOCK_MONOTONIC
    #define CLOCK_MONOTONIC 0       /* not used anyway */
    #endif
    #endif
    
    int main(int argc, char **argv)
    {
        time_t now_sec;
        struct tm *now;
        FILE *bout;
        struct timespec now_clk;
        if (argc < 2)
        {
            printf("Usage: %s build_file_name\n\n", argv[0]);;
            return EXIT_FAILURE;
        }
        bout = fopen(argv[1], "a");
        if (!bout)
        {
            printf("Could not open file: %s\n\n", argv[1]);
            return EXIT_FAILURE;
        }
        time(&now_sec);
        now = gmtime(&now_sec);
        fprintf(bout, "%02d/%02d/%04d %02d:%02d:%02d", now->tm_mday, now->tm_mon+1, now->tm_year+1900, now->tm_hour, now->tm_min, now->tm_sec);
        clock_gettime(CLOCK_MONOTONIC, &now_clk);
        fprintf(bout, " %ld\n", now_clk.tv_nsec);
        return EXIT_SUCCESS;
    }
    

    Hopefully this will be of help to someone.

    Update

    After ~9 months of using this, I can say this has been quite useful. Some observations are:

    • On Windows, the last element given by the implementation of clock_gettime is quite small, half of the times with the same value. Nevertheless, it still makes it a bit more random.
    • On Linux, the last element is indeed quite random.
    • Every now and then I had to do a "Build" commit just to get the lines in the build files committed so I can merge. However, this can be avoided with git stash.
    • Using this almost always results in a conflict when merging, but is very trivial to resolve it (just remove the diff markers as lines from both files are wanted).
    • wc -l is your friend.

    这篇关于当多个作者使用版本控制时,如何跟踪库的构建计数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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