亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

go-git:創建本地分支的正確方法,模擬“git分支<分支名稱>”的行為?

go-git:創建本地分支的正確方法,模擬“git分支<分支名稱>”的行為?

Go
瀟湘沐 2022-08-24 17:00:59
正如標題所示,我正在嘗試弄清楚如何以與Git CLI命令相同的結果的方式創建本地分支。go-gitgit branch <branchname>據我所知,(沒有明確的論據)做了兩件事:git branch <branchname><start-point>創建以指向當前提交.git/refs/heads/<branchname>HEAD用一行記錄分支的創建。.git/logs/refs/heads/<branchname>它可能會做得更多,但我知道這兩件事肯定是肯定的。(如果您知道更多的東西,請分享!接下來的大部分內容都記錄了我在研究我的選擇時的發現之旅,我想我現在可能已經掌握了上面的#1。但是,對于#2,我開始認為我可能是SOL,至少使用.go-git第一個想法:Repository.CreateBranch我最初天真的想法是打電話,并且有一個類似的SO問題的答案(“如何使用go-git簽出一個新的本地分支?”),這似乎可以證明這個想法是可信的。但是一旦我開始研究細節,事情就變得非常混亂。Repository.CreateBranch首先,采用 as 輸入(為什么?),并且似乎還修改了存儲庫的文件(再次,為什么?)。我已經驗證了該命令沒有觸及存儲庫的配置,并且當我調用該命令時,我當然不需要提及有關配置的任何內容。Repository.CreateBranchconfig.Config.git/configgit branch <branchname>其次,我上面鏈接的SO答案引用了 中的代碼,該代碼執行以下操作:go-gitrepository_test.gor, _ := Init(memory.NewStorage(), nil) // init repotestBranch := &config.Branch{    Name:   "foo",    Remote: "origin",    Merge:  "refs/heads/foo",}err := r.CreateBranch(testBranch)但的定義是:config.Branchtype Branch struct {    // Name of branch    Name string    // Remote name of remote to track    Remote string    // Merge is the local refspec for the branch <=== ???    Merge plumbing.ReferenceName    ...}并且不是 refspec(因為 refspec 有一個分離它的和組件)。"refs/heads/foo":srcdst經過大量的撓頭和代碼閱讀,我得出了(非常)初步的結論,即注釋中的“refspec”一詞一定是錯誤的,它應該只是“ref”。但我完全不確定這一點:如果我是對的,那么為什么這個字段被命名而不是僅僅命名?MergeRef另一個初步的結論是,這并不是為了創建一個純粹的本地分支,而是為了創建一個本地分支,它與遠程分支有某種關系 - 例如,如果我從遠程數據庫中提取其他人的分支。Repository.CreateBranch實際上,在重讀 Repository.CreateBranch 方法時,我根本不相信它真的創建了一個分支(也就是說,它創建了 )。除非我錯過了一些東西(完全有可能),否則它似乎所做的就是在 中創建一個部分。但是,如果這是真的,為什么它是一種存儲庫的方法呢?為什么它不是一種方法?.git/refs/heads/<branchname>[branch "<name>"].git/configconfig.Config同樣,還有一個相關的函數:func (r *Repository) Branch(name string) (*config.Branch, error)只會從配置中返回分支信息。然而,文檔中的下一個函數是:Repositoryfunc (r *Repository) Branches() (storer.ReferenceIter, error) 它確實返回了 中所有條目的迭代器。.git/refs/heads/這是非常令人困惑的,文檔(就像它一樣)無濟于事。無論如何,除非有人能說服我,否則我很確定這對實際創建分支沒有多大幫助。CreateBranch
查看完整描述

2 回答

?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

首先,我沒有足夠的聲譽來評論Pedro的答案,但他的方法在階段失敗了,因為實際上沒有在存儲上創建分支(從未調用存儲庫)。CheckoutStorer


其次,這是我第一次聽說dir,所以不,不會為該dir中的分支創建記錄。.git/loggit branch


這就引出了實際的解決方案,即作為 go-git 存儲庫分支的示例提供的解決方案。


要創建分支(脫離 HEAD):

Info("git branch test")

branchName := plumbing.NewBranchReferenceName("test")

headRef, err := r.Head()

CheckIfError(err)

ref := plumbing.NewHashReference(branchName, headRef.Hash())

err = r.Storer.SetReference(ref)

CheckIfError(err)

簽出分支

Info("git checkout test")

w, err := r.Worktree()

CheckIfError(err)

err = w.Checkout(&git.CheckoutOptions{Branch: ref.Name()})

CheckIfError(err)

但是,這樣,在 中沒有此分支的配置,因此應該有對函數的調用,但這確實是可笑的不直觀的。.git/configrepo.Branch


查看完整回答
反對 回復 2022-08-24
?
GCT1015

TA貢獻1827條經驗 獲得超4個贊

我做到了:


創建對新分支的本地引用


branchName := "new-branch"

localRef := plumbing.NewBranchReferenceName(branchName)

創建分支


opts := &gitConfig.Branch{

    Name:   branchName,

    Remote: "origin",

    Merge:  localRef,

}


if err := repo.CreateBranch(opts); err != nil {

    return err

}

如果您確實需要更改為該分支...只是做一個結帳(不記得它是否實際更改為創建的分支與創建)


獲取工作樹


w, err := repo.Worktree()

if err != nil {

    return rest.InternalServerError(err.Error())

}

收款處


if err := w.Checkout(&git.CheckoutOptions{Branch: plumbing.ReferenceName(localRef.String())}); err != nil {

    return nil

}

如果要跟蹤遠程分支


創建遠程引用


remoteRef := plumbing.NewRemoteReferenceName("origin", branchName)

跟蹤遠程


newReference := plumbing.NewSymbolicReference(localRef, remoteRef)


if err := repo.Storer.SetReference(newReference); err != nil {

   return err

}


查看完整回答
反對 回復 2022-08-24
  • 2 回答
  • 0 關注
  • 303 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號