【问题标题】:git commit symlink as a regular filegit commit 符号链接作为常规文件
【发布时间】:2011-12-12 05:34:16
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您好,您能更新一下使用 Git 对文件进行符号链接的步骤吗?

标签: git symlink


【解决方案1】:

如果您希望显示文件而不是链接,您可能应该使用ln 命令创建硬链接而不是符号链接 (ln -s)。

制作硬链接,您可以使同一个文件出现在两个不同的目录下,因此通过任何链接更改它都会反映两个链接的更改,并且文件将存在于两个目录中,因此它将是由git跟踪。

我希望 Bukov's answer 中的 Windows 的 mklink /j 命令能做到这一点,但我真的不知道。

【讨论】:

  • 这个答案对我来说似乎比@Jefromi 的答案更有帮助。
  • 需要注意的是ln的硬链接只对文件有效,对目录无效。
  • 正是我搜索的内容!向 UNIX 系统致敬!
  • ❗️硬链接不能保证在 OSX 上可靠工作——通常当应用程序更新源文件时,链接被切断,你最终得到两个单独的文件,前链接现在指向旧内容.
  • 如果文件被删除和覆盖,这将不起作用,例如当前的xdg-mime bug。 :'( git precommit hook 似乎是这里最明智的选择。
【解决方案2】:

不,Git 知道这是一个符号链接。 Git 假装不这样做会有点危险,因为它最终会写入存储库外部的文件。将其作为符号链接进行跟踪正是预期的行为。

【讨论】:

  • 我希望这种情况下的写入行为是删除符号链接并将其替换为常规文件。
  • @hasenj:如果这是您想要的,请删除符号链接并将其替换为链接文件的副本。您的“预期”行为涉及 Git 修改文件...添加?犯罪?这也不是什么好事。
  • 让符号链接指向您的 git 存储库更有可能有用。如果您有一个用于系统配置的存储库,然后您将 git 管理的配置文件替换为指向已签出存储库中文件的链接,就会出现这种情况。
【解决方案3】:

在 Windows 中,您可以使用 Junction 为所欲为

例如,程序通常会在系统的某个位置保存一个设置文件,但我想在我的存储库中对其进行版本控制。我无法移动文件,也不想复制或做任何事情

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

我们需要的是能够在存储库中放置类似的 Windows 快捷方式,但 git 会将其视为另一个文件夹:

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

【讨论】:

  • 如果从上游合并更改会发生什么? Git 会修改源内容吗?就像 Jefromi 在 another answer 中提到的那样,那会很危险。
【解决方案4】:

我遇到了同样的问题...将带有符号链接文件的目录上传到 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

【讨论】:

    猜你喜欢
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    相关资源
    最近更新 更多