维护一组不会被提交给SCM的小改动

时间:2011-04-01 13:19:42

标签: svn git version-control mercurial

我正在使用git,但我很高兴听到与其他SCM相关的答案。

我正在进行一些与我相关的小改动(使用不同的构建方案,仅与我的配置相关),我真的需要它们。

正确的做法当然是将它合并到主干中,但直到我将它合并到主干中我必须保留一个不会提交的更改列表。< / p>

所以,假设我需要将makefile更改为CC=mygcc(因为我需要gcc符号链接指向我正在编译的其他软件的错误版本),但我不想提交它(其他人没有,所以其他人不希望mygcc符号链接)。

如何让我轻松同步和更新主存储库?

3 个答案:

答案 0 :(得分:4)

这真是对Elazar Leibovich's second option的评论,这对评论来说有点失控:)在提交图条款中,我基本上和选项2一样,但维护一个本地分支,我的变化而不是留在主人身上。换句话说,通常的状态是这样的:

 A --- B --- C (master,origin/master) --- D --- E (local)

...如果我想从master更新,我会这样做:

 git checkout local
 git fetch origin
 git rebase origin/master

...到达:

A --- B --- C (master) --- F --- G (origin/master) --- D' --- E' (local)

如果我在local上添加了更多提交,我会将其设为git rebase -i origin/master,这样我就可以确保DE仍然最多最近的历史。

这比Elazar Leibovich的选项2的优势在于它降低了您使用mastergit push意外将本地更改推送到git push master的风险,因为您的本地更改永远不会在master分支上,并且远程不应该有名为local的分支。 (如果有,请选择其他名称,显然:))

如果您确实想要推送到master,请在此处提交HI

A -- B -- C (master) -- F -- G (origin/master) -- H -- I -- D'' -- E' (local)

......你会这样做:

git checkout master
git merge I
git push origin master

答案 1 :(得分:3)

在Mercurial中,最好使用mq patch

制作初始补丁:

cd <working copy>
hg qinit
...make changes to your working copy
hg qnew <patch_name>

然后,当需要从远程提取更改或实际提交新的本地更改时:

hg qpop -a        # remove all patches from your working copy
hg pull --update  # get new changesets from the remote and update to the latest
...work on local files
hg commit -m "commit changes without touching the patch"
hg push           # send changes to a remote repo that don't include the patch
hg qpush -a       # apply all patches to your updated working copy

答案 2 :(得分:2)

git我看到2个选项:

  1. 进行此更改,但绝不将其添加到索引中。没关系,但是如果您的更改跨越多个文件,并且如果您只需要对某个文件进行一些更改,则会变得很烦人(git add -p,等等,我是否需要该行...)。
  2. 始终在远程主控之前提交1次。将更改提交给master,并在提交rebase之前,以便您不想推送的提交将位于顶部。然后将所有内容推送到除上次提交之外的服务器。
  3. 让我展示一个我编写的快速脚本,以确保您的临时提交始终如一。我假设临时提交在提交消息中有#alwaysontop

    此脚本基本上在提交消息中搜索带有#alwaysontop的第一个可达提交,并在其后重新定义所有更改,以使其位于顶部。确保与您的提交和#alwaysontop提交没有冲突,否则它将无法正常工作。

    您应该确保永远不会使用pre-push hook推送标有#alwaysontop的提交。

    #!/bin/sh
    if ! git diff-index --quiet HEAD --; then
            echo "Repository is dirty, only run with clean index and working tree"
            exit -1
    fi
    
    KEYWORD=':/#alwaysontop'
    
    if ! git rev-parse $KEYWORD &>/dev/null; then
            echo No commit with $KEYWORD found
            exit -1
    fi
    
    TEMPREV=`git rev-parse $KEYWORD`
    REMOTE_BRANCH=`git rev-parse $TEMPREV^`
    
    echo @ rebasing current commit before $TEMPREV
    git rebase --onto $REMOTE_BRANCH $TEMPREV && \
    NEWHEAD=`git rev-parse HEAD` && \
    echo @ now at $NEWHEAD moving to always-on-top commit && \
    git reset --hard $TEMPREV && \
    echo @ rebasing $TEMPREV to be topmost && \
    git rebase $NEWHEAD