我已经用 git-svn 克隆了一个远程 SVN 存储库。我以代码编译的方式修改了这个克隆的 repo 中的 pom.xml 文件。这个设置是我独有的。因此,我不想将更改推送回远程仓库。
有没有办法防止文件的这种(部分)更改被提交到 repo 中?我知道我可以使用个人分支,但这意味着一定的合并开销。还有其他方法吗?
我已经研究过这个问题和这个问题,但它们是为了相当暂时的变化。
更新:我也知道 .gitignore 的可能性,但这意味着完全排除该文件。
编辑:你问的是不可能的,我没有看到“部分”部分。我知道您只能提交部分文件,但不能忽略文件的某些部分。您将需要使用 update-index 技巧来避免将其置于“状态”中,并且每次从远程变基/合并时都需要存储该文件,然后取消存储您的修改并使用更新忽略您的修改-指数。我不知道你是否可以为一系列 git 命令创建一个 git 别名,所以使用一个命令你可以执行所有这 3 个命令以避免麻烦
使用 .gitignore 文件,也不要将其推送到远程仓库:忽略 .gitignore 文件本身
在你的 .gitignore 中,你应该有
.gitignore
path/to/pom.xml
.gitignore 文件可以位于工作树的根目录,也可以位于您想要/需要的任何子目录中
可能有过滤器的可能性。但这需要进一步探索。
起点:为此过滤器实施涂抹/清洁:
git config --global filter.versionUpdate.smudge 'sed "s/<version>14.5.0<\/version>/<version>14.5.FEATURE-15<\/version>/"'
git config --global filter.versionUpdate.clean 'sed "s/<version>FEATURE-15<\/version>/<version>14.5.0<\/version>/"'
这样,在比较时文件总是相同的,因为应用了过滤器。
问题:它仍然需要调查如何找到过滤后的文件。这在工作目录中并不明显。
在 git 之外解决您的问题可能更容易。您可以在 pom.xml 中定义一个具有默认值的属性,每个人都使用该属性。对于您的独家设置,您只需${user.home}/.m2/settings.xml
使用-Dproperty=value
. 或者类似地,您可以创建另一个配置文件并根据您在 ~/.bashrc 中导出的环境变量激活它。
对于 git 解决方案,我正在通过一些纪律正确地遵循工作流程来完成您想要的事情:
git svn rebase
从 SVN 拉取新的提交,解决冲突。git rebase -i svn/trunk
(或者你的 svn 远程分支)(这将在 SVN 之上启动所有本地更改的交互式变基)git svn dcommit --dry-run @~1
(或git svn dcommit --dry-run HEAD~1
在旧版 git 中)以查看将推送到 SVN 存储库的内容;确保您的本地提交不在列表中。git svn dcommit @~1
(或git svn dcommit HEAD~1
)最终将您的更改推送到 SVN 存储库。git svn rebase
从 SVN 中提取新的提交。这听起来可能很复杂,但是一旦你习惯了它就会非常简单。基本上,你有一个(或多个)本地提交,你永远不会推送到 SVN。一年多来,我没有错误地推送提交,使用这个工作流和多个提交和存储库。例如,它对于进行一些仅限本地调试的更改非常有用(尽管为此引入环境变量或一些设置文件会更好)。
此外,这可以通过 git 中的 pre-dcommit 挂钩来增强,这将确保不会对本地更改进行 dcommit'ed。不幸的是,我没有看到一个标准的 git-svn 钩子,但是可以使用git-svn-hooks来实现这些。
共享这种配置文件的一种通用方法是:
pom.xml.template
:)pom.xml
到.gitignore
文件)实施步骤 3 的一些方法是:
在我看来,这听起来像是pre-commit hook的有力案例。在您的 .git 文件夹中,您应该有一个 hooks 文件夹。它可能有一些样本,但它们被忽略了,因为它们有一个 .sample 扩展名。如果您添加一个名为“ pre-commit ”(无扩展名)的文件,其中包含以下脚本,则该脚本将在您每次提交时运行。不要忘记通过运行“ chmod ug+x pre-commit ”使脚本可执行。
我添加了一些注释来解释每一行的作用,但基本上你将如何使用它是你将' #start '放在你不想包含在你的git提交中的代码之上,然后' #end '在该代码下方。您可以在 sed 命令中使用不同的开始和结束标志,只要确保您使用的任何语言的注释语法,编译器都会忽略它们。当您最终执行提交时,将发生以下情况:
由于这一切都包含在预提交挂钩中,因此这一切都会在您每次提交时自动发生。
预提交
#!/usr/bin/env bash
echo "Running pre-commit hook..."
set -e
export PATH=$PATH:/usr/local/bin
exit_status=0
echo "Removing supercomments..."
# Get a list of files part of this commit
files=$(git diff --cached --name-status)
# Loop through each file
for f in $(echo $files | awk '{ print $2}')
do
# Create a temp copy of the file
cp ${f} ${f}.temp
# Remove all chunks between '#start' and '#end'
sed -i '/#start/,/#end/d' ${f}
# Add the file with chunks removed
git add ${f}
# Replace file with temp file containing code you didn't want to comm
it
cp ${f}.temp ${f}
done
echo "Hook completed!"
exit $exit_status
示例用法:
测试.txt
This is a file
It's really just a test file
#start
This code is only relevant to me
When I eventually commit this file...
...please don't inclue all of this!
#end
This part of the file is important,
make sure it's included in my next commit.
添加并提交 test.txt:
git add test.txt
#
git commit -m "A great commit message."
# Running pre-commit hook...
# Removing supercomments...
# Hook completed!
# [master commit_id_1234] A great commit message.
test.txt(在 commit_id_1234 中)
This is a file
It's really just a test file
This part of the file is important,
make sure it's included in my next commit.
test.txt(提交后的本地副本)
This is a file
It's really just a test file
#start
This code is only relevant to me
When I eventually commit this file...
...please don't inclue all of this!
#end
This part of the file is important,
make sure it's included in my next commit.
注意: 您的问题需要考虑一些细微差别。听起来你有一组你想在你的文件中包含的代码,但只有在本地编译时(我假设你主要在本地开发和测试你的代码),但是你希望能够提交该开发代码和在提交之前自动删除您的“ only-locally-relevant-code ”。虽然上面的钩子应该做到这一点,但请记住“ only-locally-relevant-code ”的部分" 没有被版本控制,因为当您最终推送时它永远不会访问您的远程存储库。这可能很明显,但请确保您对此感到满意。如果您的本地副本发生问题,所有这些代码,即使它只是相关的对您来说,可能会丢失,并且无法通过简单地重新克隆存储库来恢复。
已经提出了好的想法。Prehooks 似乎最合适。其他一些需要考虑的途径可能是: - 分叉 repo 并提交所有更改 - 在同一个 repo 上提交一个单独的分支并提交 - 有一个本地分支,仅包含您在签出时选择的私有差异,并在检查之前反转在?- 应用补丁文件 - 再次可以在签入之前反转(虽然有问题)