git将symlink作为常规文件提交

时间:2011-12-12 05:34:16

标签: git symlink

假设我有一个文件fname,它是来自其他某个存储库/项目的文件的符号链接,比如../../proj2/fname

有没有办法将fname添加/提交为常规文件?

默认情况下,git似乎给出了文件模式120000,并将链接文件的路径设置为blob内容。

我知道这一点,因为git ls-tree显示文件的模式120000,git cat-file -p显示../../proj2/fname作为blob的内容。

4 个答案:

答案 0 :(得分:43)

如果要显示文件而不是链接,则应该使用ln命令创建硬链接而不是sym-link(ln -s)。

建立一个硬链接,你可以让同一个文件显示在两个不同的目录下,所以通过任何链接改变它将反映通过两个链接的变化,并且该文件将存在于两个目录中,因此它将是由git跟踪。

我希望Bukov's answer中的Windows {mklink /j命令执行此操作,但我真的根本不知道。

答案 1 :(得分:17)

不,Git知道这是一个符号链接。 Git假装其他方式会有点危险,因为它最终会写到外面的文件回购。将其作为符号链接进行跟踪正是预期的行为。

答案 2 :(得分:3)

在Windows中,您可以使用Junction

执行所需操作

例如,程序通常会在系统的某处保留一个设置文件,但我想在我的存储库中对其进行版本控制。我无法移动文件,我不想制作重复文件或其他任何内容

如果我们将Windows快捷方式放在存储库目录中,他会将其视为二进制单个文件;不是指向要包含的所有实际文件的目录

我们需要的是能够在存储库中添加类似 Windows快捷方式的功能,但该git将仅视为另一个文件夹:

cd /location/of/my/repo/  
mklink /j "_linkTo_VimSettings" "C:\Program Files (x86)\Vim"

答案 3 :(得分:0)

我遇到了同样的问题...将包含符号链接文件的目录上载到GIT存储库中,以公开发布。

GIT存储库是辅助源,而不是文件的主源,因此,我不想替换本地计算机上的符号链接。硬链接不好,因为它们会断开,并且当看起来它们是链接时并不明显。

当前解决方案是一个脚本,该脚本临时替换符号链接,使用硬链接执行git commit / push,然后恢复符号链接。 理想情况下,脚本将读取并保存符号链接信息,但现在它仅使用内置数据来确定符号链接应该是什么...

当然,这只是我用于git上传的脚本的一个“示例”。

#!/bin/perl
#
# Git Upload...
#
# 1/ Replace all symbolic links with hard links
# 2/ upload files into a GIT repository
# 3/ Restore symbolic links again.
#
# Only the list of symbolic links given in the DATA section are effected.
#
use strict;

# the relative location of files being included in git repository
my $source_prefix="../real_project/";

# note start of data
my $data_start=tell(DATA);

# Link all files needed for upload
while ( <DATA> ) {
  s/#.*$//;         # ignore comments
  s/\s+$//;         # remove end of line spaces
  next if /^$/;     # skip blank lines
  my($file, $source) = split;

  unlink($file);
  link("$source_prefix$source", $file)
     or warn("failed to find: $source");
}

system("git add -A");
system("git commit -a -m 'Software Export Update'");
system("git push");

# rewind data section
seek DATA, $data_start, 0;

# unlink all files that have now been uploaded
while (<DATA>) {
  s/#.*$//;         # ignore comments
  s/\s+$//;         # remove end of line spaces
  next if /^$/;     # skip blank lines
  my($file, $source) = split;

  unlink($file);
  symlink("$source_prefix$source", $file);
  #  or warn("failed to find: $source");
}

__DATA__

### Example symbolic links (to replace and restore)
  script.pl.txt            scripts/script
  data_file.txt            lib/data_file.dat

# this file is not a symlink as a it slightly modified
# but listed to keep a record of its original source
# config_example.txt       extra/config