git commit 符号链接作为常规文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8470315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 06:14:58  来源:igfitidea点击:

git commit symlink as a regular file

gitsymlink

提问by hasen

Suppose I have a file fnamewhich is a symlink to a file from some other repository/project, say ../../proj2/fname.

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

Is there a way to add/commit fnameas a regular file?

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

It seems that, by default, git gives the file mode 120000 and sets the path to the linked file as the blob content.

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

I know this because git ls-treeshows mode 120000 for the file, and git cat-file -pshows ../../proj2/fnameas the blob's content.

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

采纳答案by Cascabel

Nope, Git knows it's a symlink. It'd be kind of dangerous for Git to pretend otherwise, since it would then end up writing to files outsidethe repo. Tracking it as a symlink is exactly the intended behavior.

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

回答by mgarciaisaia

If you want the file to appear instead of the link, you should probably use the lncommand to create a hard-link instead of a sym-link (ln -s).

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

Making a hard-link, you can make the same file to appear under two different directories, so changing it via any of the links will reflect changes via both links, and the file will live in both directories, so it will be tracked by git.

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

I hope Windows' mklink /jcommand in Bukov's answerdoes this, but I really don't know at all.

我希望Bukov 的回答中的Windowsmklink /j命令可以做到这一点,但我真的一点也不知道。

回答by Bukov

In Windows, you can do what you want with a Junction

在 Windows 中,您可以使用 Junction 做您想做的事

For example, programs often keep a settings file somewhere on the system, but I'd like to version control it in my repository. I can't move the file, and I don't want to make duplicates or anything

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

If we put a Windows Shortcut in the repository directory though, he'll see it as a binary single file; not a directory pointing to all the actual files you want to include

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

What we need is the ability to put something likea Windows shortcut in the repository, but that git will treat as just another folder:

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

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

回答by anthony

I had the same problem... Uploading a directory with symlinked files into a GIT repository, for public release.

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

The GIT repository is secondary source, not the primary source of the files, as such I do not want to replace the symlinks on my local machine. Hardlinks are no good as these get broken, and it is not obvious when looking that they are links.

GIT 存储库是次要来源,而不是文件的主要来源,因此我不想替换本地计算机上的符号链接。硬链接不好,因为它们会损坏,并且在查看它们是链接时并不明显。

The current solution was a script that temporarily replaces the symlinks, with hard links does the git commit/push, then restores the symlinks. Ideally the script would read and save the symlink info, but right now it just uses built in data on what the symlinks should be...

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

Of course this is only an 'example' of the script I use for git upload.

当然,这只是我用于 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