Home > Software design >  How to run the first version of git from 2005?
How to run the first version of git from 2005?

Time:07-12

The first version of git appeared in 2005. For curiosity and learning purposes, I'm trying to get it to run. Source code here. There are very few files, so it seems reasonable, however I'm getting stuck due to lack of knowledge of C-specifics.

What step-by-step instructions will get this to run on macOS (preferably) or FreeBSD, modifying the files as needed?

Attempt 1

Using macOS Big Sur:

  1. in Makefile, change install $(PROG) $(HOME)/bin/ to install $(PROG) ./bin/
    This is to let binaries resides in the local directory.
  2. in cache.h, add the lines #include <string.h> and #include <unistd.h>.
  3. brew install openssl
  4. ln -s ../opt/openssl/include/openssl .
  5. make install

Result: Wall of errors and warnings including "no member named 'st_ctim' in 'struct stat'", "no member named 'st_mtim' in 'struct stat'", etc.

Attempt 2

Using FreeBSD 12:

  1. in Makefile, change install $(PROG) $(HOME)/bin/ to install $(PROG) ./bin/
    This is to let binaries resides in the local directory.
  2. in cache.h, add the lines #include <string.h> and #include <unistd.h>.
  3. make install

Linker errors:

/usr/local/bin/ld: read-cache.o:cache.h:64: multiple definition of `sha1_file_directory'; update-cache.o:cache.h:64: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:65: multiple definition of `active_cache'; update-cache.o:cache.h:65: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_nr'; update-cache.o:cache.h:66: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_alloc'; update-cache.o:cache.h:66: first defined here
/usr/local/bin/ld: update-cache.o: undefined reference to symbol 'SHA1_Init@@OPENSSL_1_1_0'
/usr/local/bin/ld: /lib/libcrypto.so.111: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
*** Error code 1

I'm hitting a wall, because I notice my knowledge of C and gcc is too limited to proceed. What are some pointers to make this work for macOS (preferably) or FreeBSD (otherwise)?

CodePudding user response:

The original version of Git was almost certainly only targeted toward Linux and not toward any other systems. Consequently, portability issues were probably not resolved.

This is, at most, a partial solution to your problems — it should help you with one aspect of the troubles you identify.

You say:

Result: Wall of errors and warnings including "no member named 'st_ctim' in 'struct stat'", "no member named 'st_mtim' in 'struct stat'", etc.

That feature requires a macOS-specific macro to be defined:

/* To get the 64-bit inode structure with struct timespec elements on Mac OS X */
#define _DARWIN_USE_64_BIT_INODE

The names of the structure elements are not consistent with POSIX. In my code, I use:

#define ST_ATIME st_atimespec
#define ST_BTIME st_birthtimespec
#define ST_CTIME st_ctimespec
#define ST_MTIME st_mtimespec

The POSIX variants use (file birth time is not part of POSIX):

#define ST_ATIME st_atim
#define ST_CTIME st_ctim
#define ST_MTIME st_mtim

For systems other than macOS and POSIX-compliant systems, I use these (and the type of the members is time_t, not struct timespec):

#define ST_ATIME st_atime
#define ST_CTIME st_ctime
#define ST_MTIME st_mtime

That's one part of the issue — you also have to find where st_ctim etc are used and revise the code to handle the portability issues. For example, one piece of code reads:

    struct stat *sb;

    …

        case 'a':
            pr_format_date(sb->ST_ATIME);
            break;
        case 'c':
            pr_format_date(sb->ST_CTIME);
            break;
        case 'm':
            pr_format_date(sb->ST_MTIME);
            break;

The called function is passed a Time *, where the code has one of these in effect:

typedef struct timespec Time;
typedef time_t          Time;

The body of the function has different code for when Time is a struct timespec and when it is a time_t.

  • Related