2

我在本地存储库中使用“git branch -b branch-name origin/branch-name”在本地跟踪了一个远程跟踪分支。我的远程分支是 test2/test2 (origin/branch-name),它在本地被跟踪为 test2。

原点也被命名为 test2。我还没有签出我的本地跟踪分支 test2。

当我执行“git pull origin remote-branch:local-tracked-branch”时出现此错误

[test2]$ git pull test2 test2:test2 来自 /gitvobs/git_bare/test2 ![拒绝] test2 -> test2(非快进)

而当我签出我的本地跟踪分支 test2 并执行 pull 'git pull origin local-tracked-branch' 时,我没有收到错误消息,我使用 'git pull test2 test2' 进行了 pull

从 /gitvobs/git_bare/test2 * 分支 test2 -> FETCH_HEAD 自动合并 a.txt 自动合并失败;修复冲突,然后提交结果。

我知道添加一个 + (git pull test2 +test2:test2) 会有所帮助,但它会覆盖本地更改。

那么我如何知道我的哪些本地分支是由我在本地使用“git branch new-branch-name”创建的,或者是使用 git branch -b branch-name origin/branch-name 从远程分支本地跟踪的?

4

2 回答 2

7

git pull混乱

过度特异性

您的git pull命令包含太多信息。

[test2]$ git pull test2 test2:test2
来自 /gitvobs/git_bare/test2
![拒绝] test2 -> test2(非快进)

我知道添加一个 + (git pull test2 +test2:test2) 会有所帮助,但它会覆盖本地更改。

这就是您的命令的含义:

#             *------------ (1) remote repository name
#            /     *------- (2) ref in remote repository
#           /     /     *-- (3) ref in  local repository
#          /     /     /
git pull test2 test2:test2

# Means this: From remote repository `test2` (1),
# fetch branch `test2` (2), store it in local branch `test2` (3), then
# merge the fetched history into HEAD.

您是在告诉git pulltest2用远程在其分支上的任何内容覆盖您的本地分支test2,然后将其与 HEAD 合并。您可能不想包含 refspec 的目标部分(:test2)。


如果您已签出的本地分支配置为跟踪某些内容(请参阅下面的“分支:...”),只需执行

git pull

如果您需要提供(或覆盖)远程和存储库,只需提供远程名称/url 和远程上的本地分支(省略 refspec 的最后部分):

git pull test2 test2

拉入未签出的分支

git pull是(如上所述)git fetchgit merge(或git rebase)的组合。

通常,合并可能涉及冲突解决。解决冲突需要工作树。因此,没有工作树就不可能执行正常的合并操作。这意味着您当前的 HEAD 必须是合并的父级之一(它将是第一个父级)。进行 rebase 还需要一个工作树来解决冲突。

由于拉取涉及合并或变基,因此无法拉入未签出的本地分支。您只能拉入当前签出的分支。

分支:本地、跟踪、远程跟踪

各种类型的 Git 分支都是同一个底层对象:refs。Refs 位于 和 的命名refs/空间中。$GIT_DIR/refs/$GIT_DIR/packed-refs

  • “本地”分支存在于refs/heads/命名空间中。
    • 要检查test2本地分支参考:
      • git show-ref refs/heads/test2, 或者
        • cat .git/refs/heads/test2, 或者
        • grep -F refs/heads/test2 .git/packed-refs
  • “远程跟踪”分支存在于refs/remotes/<remote-name>/命名空间中。
    • 远程跟踪分支是来自远程存储库的分支的本地副本。
      • 当您这样想时,“远程跟踪”这个名称是有道理的,但它可能会与git branchgit checkout--track不幸命名的功能混淆(请参阅最终分支类型)。
    • 检查test2远程跟踪分支参​​考:
      • git show-ref refs/remotes/test2/test2, 或者
        • cat .git/refs/remotes/test2/test2, 或者
        • grep -F refs/remotes/test2/test2 .git/packed-refs
  • 跟踪另一个分支的本地分支是正常的本地分支 (in refs/heads/),在 中具有额外的配置$GIT_DIR/config

    [branch "test2"]
            remote = test2
            merge = refs/heads/test2
    

    重要的是要注意merge(或)配置选项在远程rebase命名一个ref 。所以这里的意思是在远程找到的本地分支。特殊的远程名称可用于引用本地存储库中的本地分支。refs/heads/test2test2test2.

    • “跟踪”其他分支的本地分支的目的是使其易于键入git pull并使其合并(或在其之上)其他分支的历史记录。

您说您想将普通的本地分支与跟踪其他分支的本地分支区分开来。您可以通过在$GIT_DIR/config文件中查找分支配置来执行此操作。

您可以使用git config来执行此操作:

branch_tracks_something() {
    {
        git config branch."$1".merge ||
        git config branch."$1".rebase
    } >/dev/null 2>&1
}
# test local branch 
branch_tracks_something test2 && echo 'test2 tracks something' || echo 'test2 does not track anything'

或者,如果你有 Git 1.6.3 或更高版本,你可以使用git for-each-ref%(upstream)的格式:

{ echo 'show_ref_desc() {
    case "$1" in
        refs/heads/*)
            t=''
            test -n "$2" && t=" (tracks $2)"
            echo "local: $1$t"
        ;;
        refs/remotes/*)
           echo "remote tracking: $1"
        ;;
        *)
            echo "other: $1"
        ;;
    esac
}'; git for-each-ref --shell --format='show_ref_desc %(refname) %(upstream)'; } |
sh

输出如下所示:

local: refs/heads/test2 (tracks refs/remotes/test2/test2)
remote tracking: refs/remotes/test2/HEAD
remote tracking: refs/remotes/test2/test2
于 2010-05-22T21:22:14.500 回答
1

独立于跟踪的分支列表(您可以使用 看到git config -l),non-fast-forward”消息意味着无法在您的分支中合并远程分支(即远程分支的已获取提交的本地副本),因为:

  • 你的分支有自己的提交
  • 远程分支自上次拉取以来有新的提交

所以:

  --last pull
  |
  v
x-x-x-x-x <--test2
  \
   -y-y-y <-- test2/test2

而这将是一个快进合并

  --last pull
  |
  v
x-x <--test2
  \
   -y-y-y <-- test2/test2

所以:

git checkout test2
git fetch test2 test2 
git merge test2/test2
#fix conflicts
git commit

请务必将您的远程仓库称为 test2 以外的任何名称。这里的 test2 太多了;)


现在查看本地仓库中跟踪的远程分支列表:

git config --get-regexp branch..*
于 2010-05-22T07:30:21.850 回答