13

我已经用 git-svn 克隆了一个远程 SVN 存储库。我以代码编译的方式修改了这个克隆的 repo 中的 pom.xml 文件。这个设置是我独有的。因此,我不想将更改推送回远程仓库。

有没有办法防止文件的这种(部分)更改被提交到 repo 中?我知道我可以使用个人分支,但这意味着一定的合并开销。还有其他方法吗?

我已经研究过这个问题和这个问题,但它们是为了相当暂时的变化。

更新:我也知道 .gitignore 的可能性,但这意味着完全排除该文件。

4

6 回答 6

5

编辑:你问的是不可能的,我没有看到“部分”部分。我知道您只能提交部分文件,但不能忽略文件的某些部分。您将需要使用 update-index 技巧来避免将其置于“状态”中,并且每次从远程变基/合并时都需要存储该文件,然后取消存储您的修改并使用更新忽略您的修改-指数。我不知道你是否可以为一系列 git 命令创建一个 git 别名,所以使用一个命令你可以执行所有这 3 个命令以避免麻烦

使用 .gitignore 文件,也不要将其推送到远程仓库:忽略 .gitignore 文件本身

在你的 .gitignore 中,你应该有

 .gitignore
 path/to/pom.xml

.gitignore 文件可以位于工作树的根目录,也可以位于您想要/需要的任何子目录中

于 2012-06-20T08:52:49.593 回答
2

可能有过滤器的可能性。但这需要进一步探索。

起点:为此过滤器实施涂抹/清洁:

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>/"'

这样,在比较时文件总是相同的,因为应用了过滤器。

问题:它仍然需要调查如何找到过滤后的文件。这在工作目录中并不明显。

涂抹清洁过滤器

于 2018-01-24T09:23:10.717 回答
2

在 git 之外解决您的问题可能更容易。您可以在 pom.xml 中定义一个具有默认值的属性,每个人都使用该属性。对于您的独家设置,您只需${user.home}/.m2/settings.xml使用-Dproperty=value. 或者类似地,您可以创建另一个配置文件并根据您在 ~/.bashrc 中导出的环境变量激活它。

对于 git 解决方案,我正在通过一些纪律正确地遵循工作流程来完成您想要的事情:

  1. 对 pom.xml(或其他文件)进行特定于设置的更改。
  2. 将更改提交到 git(仅限本地)。在提交标题/消息中说明更改仅供本地使用,例如“LOCAL ONLY. DO NOT DCOMMIT: rest of the title”。
  3. 从 svn 拉取更改,进行本地 git 提交等。
  4. 一旦将您的更改提交回 svn,请执行
    1. git svn rebase从 SVN 拉取新的提交,解决冲突。
    2. git rebase -i svn/trunk(或者你的 svn 远程分支)(这将在 SVN 之上启动所有本地更改的交互式变基)
    3. 在交互式 rebase 待办事项编辑器中,将仅本地提交移至底部。
    4. 保存待办事项并退出变基待办事项编辑器。
    5. 解决任何冲突(除非您在其他本地提交中触及 pom.xml(或其他仅本地文件)的相同部分,否则应该没有冲突)。
  5. 运行git svn dcommit --dry-run @~1(或git svn dcommit --dry-run HEAD~1在旧版 git 中)以查看将推送到 SVN 存储库的内容;确保您的本地提交不在列表中。
  6. 运行git svn dcommit @~1(或git svn dcommit HEAD~1)最终将您的更改推送到 SVN 存储库。
  7. git svn rebase从 SVN 中提取新的提交。

这听起来可能很复杂,但是一旦你习惯了它就会非常简单。基本上,你有一个(或多个)本地提交,你永远不会推送到 SVN。一年多来,我没有错误地推送提交,使用这个工作流和多个提交和存储库。例如,它对于进行一些仅限本地调试的更改非常有用(尽管为此引入环境变量或一些设置文件会更好)。

此外,这可以通过 git 中的 pre-dcommit 挂钩来增强,这将确保不会对本地更改进行 dcommit'ed。不幸的是,我没有看到一个标准的 git-svn 钩子,但是可以使用git-svn-hooks来实现这些。

于 2019-08-28T04:59:08.850 回答
2

共享这种配置文件的一种通用方法是:

  1. 提交一个模板文件(例如pom.xml.template:)
  2. 忽略文件本身(例如:添加pom.xml.gitignore文件)
  3. 让每个用户自定义此文件以满足他的需要

实施步骤 3 的一些方法是:

  • 让用户手动编辑复制模板文件并进行编辑
  • 有一些脚本,它在模板文件上应用替换并将输出写入预期的目标
于 2019-08-28T08:35:17.300 回答
2

在我看来,这听起来像是pre-commit hook的有力案例。在您的 .git 文件夹中,您应该有一个 hooks 文件夹。它可能有一些样本,但它们被忽略了,因为它们有一个 .sample 扩展名。如果您添加一个名为“ pre-commit ”(无扩展名)的文件,其中包含以下脚本,则该脚本将在您每次提交时运行。不要忘记通过运行“ chmod ug+x pre-commit ”使脚本可执行。

我添加了一些注释来解释每一行的作用,但基本上你将如何使用它是你将' #start '放在你不想包含在你的git提交中的代码之上,然后' #end '在该代码下方。您可以在 sed 命令中使用不同的开始和结束标志,只要确保您使用的任何语言的注释语法,编译器都会忽略它们。当您最终执行提交时,将发生以下情况:

  1. 中间的代码(包括#start 和#end 标志)将被删除
  2. 该文件将在没有代码和标志的情况下提交
  3. 然后代码和标志将返回到文件的本地副本

由于这一切都包含在预提交挂钩中,因此这一切都会在您每次提交时自动发生。

预提交

#!/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 ”的部分" 没有被版本控制,因为当您最终推送时它永远不会访问您的远程存储库。这可能很明显,但请确保您对此感到满意。如果您的本地副本发生问题,所有这些代码,即使它只是相关的对您来说,可能会丢失,并且无法通过简单地重新克隆存储库来恢复。

于 2019-08-30T02:25:50.970 回答
0

已经提出了好的想法。Prehooks 似乎最合适。其他一些需要考虑的途径可能是: - 分叉 repo 并提交所有更改 - 在同一个 repo 上提交一个单独的分支并提交 - 有一个本地分支,仅包含您在签出时选择的私有差异,并在检查之前反转在?- 应用补丁文件 - 再次可以在签入之前反转(虽然有问题)

于 2019-08-30T09:22:00.047 回答