Git and hard links

后端 未结 4 624
囚心锁ツ
囚心锁ツ 2020-11-28 04:31

Considering that Git does not recognize symbolic links that point outside of the repository, is there any problem using hard links?

Could Git break them? Can you pl

相关标签:
4条回答
  • 2020-11-28 04:57

    Google 'git preserve hard links' and it shows that git does not know how to preserve hard link structure AFAIK, perhaps by design.

    Web projects of mine use hard links as follows:

    www/products/index.php
    www/products/dell_latitude_id577/index.php #(hard linked to above)
    www/products/dell_inspiron_id323/index.php #(hard linked again to above)
    
    me@server:www/products$ ls -l index.php
    -rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*
    

    If I wanted to make changes to index.php I change it in one place and the hard links (product detail pages) point to the changes -- except git does not preserve this relationship during cloning and pulling on other computers.

    me@server:www$ git pull
    

    on another machine will create a new index.php for each hard link.

    0 讨论(0)
  • 2020-11-28 04:59

    The 'tree' object, representing directories in Git, stores file name and (subset of) permissions. It doesn't store inode number (or other kind of file id). Therefore hard links cannot be represented in git, at least not without third party tools such as metastore or git-cache-meta (and I am not sure if it is possible even with those tools).

    Git tries to not touch files that it doesn't need to update, but you have to take into account that git doesn't try to preserve hardlinks, so they can be broken by git.


    About symbolic links pointing outside repository: git has no problems with them and should preserve contents of symbolic links... but utility of such links is dubious to me, as whether those symlinks would be broken or not depends on the filesystem layout outside git repository, and not under control of git.

    0 讨论(0)
  • 2020-11-28 04:59

    From this msysgit issue

    Junction points are not symbolic links; therefore, symbolic links are simply unsupported in msysGit.

    Also, hard links were never tracked by Git.

    The issue were Windows-oriented (since it is about msysgit) and debate about the potential support of symlink.
    But the comment about hard link concerns Git in general.

    0 讨论(0)
  • 2020-11-28 05:20

    I found out that, using hooks, you can capture the git pull event (when there is something to pull...) writing the script event handler to .git/hooks/post-merge file.

    First, you have to chmod +x it.

    Then, put the ln commands inside it to recreate hard links at each pull. Neat huh!

    It works, I just needed that for my project and ls -i shows that files were automatically linked after pull.


    My example of .git/hooks/post-merge:

    #!/bin/sh
    ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
    ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
    ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
    ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf
    

    IMPORTANT: As you can see, the path to any file in your repository should begin with $GIT_DIR, then add the partial relative path to the file.

    Also important: -f is necessary, because you are recreating the destination file.

    EDIT

    Modern git client seems to support symlinks and hardlinks inside of the repository naturally, even when pushing to a remote location and then cloning from it. I never had the need again to link outside a git repo though...

    $ mkdir tmp
    $ cd tmp
    $ git --version
    git version 2.24.3 (Apple Git-128)
    $ git init .
    Initialized empty Git repository in /Users/teixeira/tmp/.git/
    $ mkdir x
    $ cd x
    $ echo 123 > original
    $ cat original
    123
    $ cd ..
    $ ln -s x/original symlink
    $ cat symlink
    123
    $ ln x/original hardlink
    $ cat hardlink
    123
    $ git add .
    $ git commit -m 'Symlink and hardlink commit'
    [master (root-commit) 8df3134] Symlink and hardlink commit
     3 files changed, 3 insertions(+)
     create mode 100644 hardlink
     create mode 120000 symlink
     create mode 100644 x/original
    

    Cloning from local git repository

    $ cd
    $ git clone tmp/ teste_tmp
    Cloning into 'teste_tmp'...
    done.
    $ cd teste_tmp/
    $ ls
    hardlink  symlink  x
    $ cat symlink
    123
    $ cat hardlink
    123
    

    Cloning from remote repository

    $ cd ~/tmp
    $ git remote add origin https://github.com/myUser/myRepo.git
    $ git push origin master
    Enumerating objects: 5, done.
    Counting objects: 100% (5/5), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
    Total 5 (delta 0), reused 0 (delta 0)
    To https://github.com/myUser/myRepo.git
     + 964dfce...8df3134 master -> master
    $ cd ../
    $ git clone https://github.com/myUser/myRepo.git
    Cloning into 'myRepo'...
    remote: Enumerating objects: 5, done.
    remote: Counting objects: 100% (5/5), done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
    Unpacking objects: 100% (5/5), done.
    $ cd myRepo/
    $ cat symlink
    123
    $ cat hardlink
    123
    

    https://github.com/mokacoding/symlinks also points an important thing: symlinks must be defined relatively.

    0 讨论(0)
提交回复
热议问题