如何查找分支是本地跟踪分支还是用户创建的本地分支?

发布于 2024-09-02 21:55:35 字数 735 浏览 3 评论 0原文

我有一个使用“gitbranch-bbranch-nameorigin/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 时 并拉 'git pull origin local-tracked-branch' 我没有收到错误 'git pull test2 test2' 进行拉取

我使用来自 /gitvobs/git_bare/test2 的 * 分支测试2-> FETCH_HEAD 自动合并a.txt 自动合并失败;修复冲突,然后提交结果。

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

那么我如何知道哪些本地分支是我在本地使用“gitbranchnew-branch-name”创建的,或者是使用“gitbranch-bbranch-nameorigin/branch-name”从远程分支本地跟踪的?

I have a remote tracking branch tracked locally in my local repository using 'git branch -b branch-name origin/branch-name'.
My remote branch is test2/test2 (origin/branch-name) which is being tracked locally as test2.

The origin is also named test2.
I haven't checked-out my local tracking branch test2.

When i do a 'git pull origin remote-branch:local-tracked-branch' i get this error

[test2]$ git pull test2 test2:test2
From /gitvobs/git_bare/test2
! [rejected] test2 -> test2 (non fast forward)

Whereas when i checkout my local tracking branch test2
and do pull 'git pull origin local-tracked-branch' i don't get the error
and i do a pull using 'git pull test2 test2'

From /gitvobs/git_bare/test2
* branch test2 -> FETCH_HEAD
Auto-merging a.txt
Automatic merge failed; fix conflicts and then commit the result.

i know that adding a + (git pull test2 +test2:test2) would help but it overwrites local changes.

So how do i know which of my local branches are created by me locally using 'git branch new-branch-name' or tracked locally from remote branches using git branch -b branch-name origin/branch-name'?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

昔梦 2024-09-09 21:55:35

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 pull 使用远程 test2 分支上的任何内容覆盖本地 test2 分支,然后将其与 HEAD 合并。您可能不想包含 refspec 的目标部分(:test2)。


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

git pull

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

git pull test2 test2

拉入未签出的分支

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

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

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

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

各种类型的 Git 分支都是相同的底层对象:refs。引用位于 $GIT_DIR/refs/$GIT_DIR/packed-refsrefs/ 命名空间中。

  • “本地”分支位于 refs/heads/ 命名空间中。
    • 要检查 test2 本地分支引用:
      • git show-ref refs/heads/test2,或者
        • cat .git/refs/heads/test2,或
        • grep -F refs/heads/test2 .git/packed-refs
  • “远程跟踪”分支位于refs/remotes// 命名空间。
    • 远程跟踪分支是远程存储库分支的本地副本。
      • 当你这样想时,“远程跟踪”这个名字是有意义的,但它可能会与 git 分支 不幸命名的 --track 功能相混淆git checkout(查看最终分支类型)。
    • 要检查 test2 远程跟踪分支引用:
      • git show-ref refs/remotes/test2/test2,或
        • cat .git/refs/remotes/test2/test2,或
        • grep -F refs/remotes/test2/test2 .git/packed-refs
  • 跟踪另一个分支的本地分支是普通的本地分支(在 refs/heads/ 中),在 $GIT_DIR/config 中具有额外的配置:

    [分支“test2”]
            远程=测试2
            合并 = refs/heads/test2
    

    值得注意的是,merge(或rebase)配置选项在远程命名了一个引用。所以这里的 refs/heads/test2 表示在远程 test2 上找到的本地分支 test2 。特殊的远程名称 . 可用于引用本地存储库中的本地分支。

    • “跟踪”其他某个分支的本地分支的目的是让您可以轻松地键入 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 的 %(upstream) 格式-each-ref:

{ 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

git pull Confusion

Over-specificity

Your git pull command includes too much information.

[test2]$ git pull test2 test2:test2
From /gitvobs/git_bare/test2
! [rejected] test2 -> test2 (non fast forward)

i know that adding a + (git pull test2 +test2:test2) would help but it overwrites local changes.

This is what your command means:

#             *------------ (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.

You are telling git pull to overwrite your local test2 branch with whatever the remote has on its test2 branch and then merge that with HEAD. You probably do not want to include the destination part of the refspec (the :test2).


If the local branch you have checked out is configured to track something (see the “Branches: …” below), just do

git pull

If you need to supply (or override) a remote and repository, just supply the remote name/url and the local branch on the remote (leave off the final part of the refspec):

git pull test2 test2

Pull Into a Branch That is Not Checked Out

git pull is (as mentioned above) a combination of git fetch and git merge (or git rebase).

In general, a merge might involve conflict resolution. Conflict resolution requires a working tree. Therefore, it is not possible to perform a normal merge operation without a working tree. This means that your current HEAD has to be one of parents of the merge (it will be the first parent). Doing a rebase also needs a working tree for conflict resolution.

Since a pull involves a merge or rebase, it is not possible to pull into a local branch that is not checked out. You can only pull into the currently checked out branch.

Branches: Local, Tracking, Remote Tracking

The various types of Git branches are all the same underlying object: refs. Refs live in the refs/ namespace in $GIT_DIR/refs/ and $GIT_DIR/packed-refs.

  • “Local” branches live in the refs/heads/ namespace.
    • To examine the test2 local branch ref:
      • git show-ref refs/heads/test2, or
        • cat .git/refs/heads/test2, or
        • grep -F refs/heads/test2 .git/packed-refs
  • “Remote Tracking” branches live in the refs/remotes/<remote-name>/ namespaces.
    • Remote tracking branches are local copies of branches from a remote repository.
      • The name “remote tracking” makes sense when you think of it like this, but it can be confused with the unfortunately named --track functionality of git branch and git checkout (see the final branch type).
    • To examine the test2 remote tracking branch ref:
      • git show-ref refs/remotes/test2/test2, or
        • cat .git/refs/remotes/test2/test2, or
        • grep -F refs/remotes/test2/test2 .git/packed-refs
  • Local branches that track another branch are normal local branches (in refs/heads/) that have extra configuration in $GIT_DIR/config:

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

    It is important to note that the merge (or rebase) configuration option names a ref on the remote. So refs/heads/test2 here means the local branch test2 found on the remote test2. The special remote name . can be used to refer to local branches in the local repository.

    • The purpose of local branches that “track” some other branch is to make it easy to just type git pull and have it merge in (or rebase on top of) the history in some other branch.

You said that you wanted to distinguish plain plain local branches from local branches that track some other branch. You can do this by looking for the branch configuration in the $GIT_DIR/config file.

You might use git config to do this:

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'

Or, if you have Git 1.6.3 or later, you can use the %(upstream) format of git for-each-ref:

{ 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

The output looks like this:

local: refs/heads/test2 (tracks refs/remotes/test2/test2)
remote tracking: refs/remotes/test2/HEAD
remote tracking: refs/remotes/test2/test2
青春如此纠结 2024-09-09 21:55:35

独立于跟踪分支列表(您可以使用 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..*

Independently of the list of tracked branched (which you can see with git config -l), a "non-fast-forward" message means cannot merge the remote branch (i.e. the local copy of the fetched commit of the remote branch) in your branch because:

  • your branch has commits of its own
  • the remote branch has new commits since the last pull

so:

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

Whereas this would have been a fast-forward merge

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

So:

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

And please, do call your remote repo any other name than test2. That is way too many test2 here ;)


Now for the list of remote branches tracked in your local repo:

git config --get-regexp branch..*
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文