简体   繁体   English

如何配置git来覆盖非文本文件而不是版本控制呢?

[英]how to config git to overwrite non text file instead of version controlled it?

If I have a git repository that has both source code and other types of file, such slides, binary, etc. I want git to just version control the text file ( such as source code ). 如果我有一个包含源代码和其他类型文件的git存储库,这样的幻灯片,二进制等等。我希望git只是版本控制文本文件(例如源代码)。 For other file types (binaries, for example), I just want to store one copy in the git repository, ie I want git to overwrite the file whenever I update it. 对于其他文件类型(例如二进制文件),我只想在git存储库中存储一个副本,即每当我更新它时我都希望git覆盖该文件。 I don't want to store multiple version for other types of file as they may be very large. 我不想为其他类型的文件存储多个版本,因为它们可能非常大。 Is there a way to config git for that purpose ? 有没有办法为此目的配置git? I run my own git host. 我运行自己的git主机。

Thanks in advance! 提前致谢!

add and commit all files you want to store in the repo once in a separate commit. addcommit 一旦在一个单独的承诺要在回购来存储所有文件。
first commit should be of a file you want to keep track of (ie the text file). 第一次提交应该是您要跟踪的文件(即文本文件)。

each time you change a file which you want to keep track of, you make a new commit like you normally do. 每次更改要跟踪的文件时,都会像平常一样进行新的提交。
each time you change a file which you want to be stored once, you make a new commit and rebase / fixup the commit to the commit that added the binaries. 每次更改要存储一次文件时,你犯了一个新的提交和rebase / fixup提交到提交将添加的二进制文件。


here is the idea in practice: 这是实践中的想法:

$ ls
banana.pdf  bar.bin  foo.txt  mew.ppt

$ git status -s
?? banana.pdf
?? bar.bin
?? foo.txt
?? mew.ppt

add files - first the files to keep track of then all the binaries 添加文件 - 首先是文件以跟踪所有二进制文件

$ git add foo.txt
$ git commit -m "foo text file"

$ git tag "root" HEAD   # easy access to the first commit

$ git add banana.pdf bar.bin mew.ppt
$ git commit -m "binaries"

make changes and commits 进行更改和提交

$ echo "ohai, I'm a change :D" >> foo.txt
$ git add foo.txt
$ git commit -m "foo changed"

$ echo "ohai, I'm a banana" | hexdump >> banana.pdf
$ git add banana.pdf
$ git commit -m "fixup! binaries"

lets look at what we have 让我们看看我们有什么

$ git log --oneline
42c09bd fixup! binaries     # this will be merge with
a9b1853 foo changed
8899046 binaries            # this - same commit message!
7c8ae05 foo text file       # this is also the 'root' tag

now rebase the commits to fixup the commits for the binaries 现在修改提交以修复二进制文件的提交

$ git rebase --autosquash -i root    # everything will be ready for us
pick 8899046 binaries
fixup 42c09bd fixup! binaries        # notice this :)
pick a9b1853 foo changed
:wq                                  # vim save and quit

$ git log --oneline                  # lets look at what we end up with
41e1f09 foo changed
50adb90 binaries
7c8ae05 foo text file

it is very important to mark the new commit for the " non-tracked " file as 将“ 未跟踪 ”文件的新提交标记为非常重要

git commit -m "fixup! <same message as the commit to merge with>"

in our case the original message of the commit that added the 'banana.pdf' was binaries 在我们的例子中,添加'banana.pdf'的提交的原始消息是binaries
so the commit message for the commit that changed any of the binaries should be fixup! binaries 所以改变任何二进制文件的提交的提交消息应该是fixup! binaries fixup! binaries (as it is in the example) fixup! binaries (在示例中)


if you do not name the commit that way then --autosquash cannot help you, and you have to manually move the line of the commit you want to change under the commit you want it to be merged with, and replace 'pick' with 'fixup', for example (continuing from where we left): 如果您没有以这种方式命名提交,那么--autosquash无法帮助您,并且您必须在要与其合并的提交下手动移动要更改的提交行,并将'pick'替换为'修复',例如(从我们离开的地方继续):

$ echo "ohai, more changes" >> bar.bin
$ git add bar.bin
$ git commit -m "changed bar"
$ git log --oneline
bd36eb9 changed bar
41e1f09 foo changed
50adb90 binaries
7c8ae05 foo text file

$ git rebase -i root
pick 50adb90 binaries      # you want this to merge with
pick 41e1f09 foo changed
pick bd36eb9 changed bar   # this

so change it to 所以改成它

pick 50adb90 binaries
fixup bd36eb9 changed bar  # under the line to be merged with and with 'fixup' instead of 'pick'
pick 41e1f09 foo changed
:wq                        # save and quit

$ git log --oneline        # what we end up with
9f94cbe foo changed
886eebd binaries
7c8ae05 foo text file

done :) 完了:)


if you want to go further you can automate this with a git hook . 如果你想进一步,你可以使用git钩子自动化它。 see 看到

$ git help githooks

a pre-commit hook would do the work for you with some tricks 一个pre-commit钩子会为你做一些技巧

Git, being a snapshot based VCS, with a cryptographically secure hash across the history, is not able to 'forget' an old version and replace it with a 'new' version of a file. 作为基于快照的VCS,Git在历史记录中具有加密安全哈希,无法“忘记”旧版本并将其替换为文件的“新”版本。 This would break its crypto security. 这将破坏其加密安全性。

Git is designed to be optimal for source code, and isn't optimal for binary files, but then neither are other VCS systems. Git被设计为源代码的最佳选择,并不是二进制文件的最佳选择,但其他VCS系统也不是。

One solution is to ignore your binary files for the git repo, but create an alias for the git commit that will detect the binary file change and replace a copy in your separate archive, assuming its that important. 一种解决方案是忽略git repo的二进制文件,但为git commit创建别名,该别名将检测二进制文件更改并替换单独存档中的副本,假设它很重要。

Do remember that if your binary files do not change very often then git is efficient about first, not storing duplicates, and second compressing those files. 请记住,如果您的二进制文件不经常更改,那么git首先是高效的,不是存储重复文件,而是第二次压缩这些文件。 You can also mark the files as --assume-unchanged (i've not used it so check the manual) so that short-term changes are ignored. 您还可以将文件标记为--assume-unchanged (我没有使用它,因此请查看手册),以便忽略短期更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM