-2

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)?

Michael
  • 637
  • 1
  • 7
  • 13
  • 1
    @Michael The question is too broad for this site, basically (I didn't DV or close). – Paul Sanders Jul 10 '22 at 23:42
  • @PaulSanders I appreciate the clarification, now I better understand the need expressed by the downvote and how to improve my communication. Moreover, thanks to your pointer, I could find a post on "too broad" over at meta that helped me understand better: https://meta.stackoverflow.com/a/259857/409246 — As a side-note, I wonder, since StackOverflow may not be the right place to get unstuck on this issue, if there are other places on the internet to turn to instead? – Michael Jul 11 '22 at 00:19
  • 1
    Pick out the individual problems, one at a time. Each one may well be suited to SO: for instance, "this 2005 C code expects unistd.h to do X, now it does Y, how do X and Y relate and what incompatibilities can I expect". You'll probably find that each of these is *already answered*, too! – torek Jul 11 '22 at 01:40
  • @torek I appreciate your comment. I think I follow the strategy—if the problem seems beyond a certain size, then do this: instead of asking the big question, break it down into subproblems and ask the subproblem on SO. – Michael Jul 11 '22 at 19:32

2 Answers2

7

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    I very much appreciate how you answered this question, Jonathan. I felt way out of my depth and didn't know how to proceed. Your pointers gave me the information needed to continue. Thank you. :) – Michael Jul 11 '22 at 19:35
  • 1
    Life might be easier working under Linux in a VM. VirtualBox works and is free (I use it a lot). – Paul Sanders Jul 11 '22 at 22:41
0

For FreeBSD 12, I managed to get it to run as follows:

  1. in Makefile, modify as follows:
    • change install $(PROG) $(HOME)/bin/ to install $(PROG) ./bin/
      This is to let binaries reside in the local directory.
    • change LIBS= -lssl to LIBS= -lssl -lcrypto -lz
      This gives the linker access to the hashing and compression libraries.
  2. in cache.h, modify as follows:
    • add the lines #include <string.h> and #include <unistd.h>.
    • add extern in front of the lines 64-66.
      See here for background on this change in GCC's behavior.
  3. make install

As an aside: How to use this

  • init-db
    Initialize a .dircache folder in the current directory. Per default, objects are put into .dircache/objects.
    Note: This command is related to the modern git init and the .git folder.
  • update-cache <list of files that have been changed/added/deleted>
    Note: this is related to modern git add.
  • show-diff
    Show changes; do files need to be added?
    Note: this is similar to modern git diff.
  • cat-file <sha1>
    Note: akin to modern git cat-file.
Michael
  • 637
  • 1
  • 7
  • 13