1

This code works as long as I'm on the master branch:

main.go:

package main

import (
    datemodlocal "192.168.0.12/gitrepo/go-module-test-dateutil.git"
    stringmodlocal "192.168.0.12/gitrepo/go-module-test-stringutil.git"
    "fmt"
    "github.com/dwschulze/go-module-test-dateutilmod"
    "github.com/dwschulze/go-module-test-stringutilmod"
)

func main() {

    fmt.Println("github:  " + stringmod.ToUpperCase("test"))
    fmt.Println("github:  " + datemod.GetTime().String())
    fmt.Println("local:  " + stringmodlocal.ToUpperCase("test"))
    fmt.Println("local:  " + datemodlocal.GetTime().String())
}

go.mod:

module module-driver

require (
    192.168.0.12/gitrepo/go-module-test-dateutil.git v0.0.1
    192.168.0.12/gitrepo/go-module-test-stringutil.git v0.0.1
    github.com/dwschulze/go-module-test-dateutilmod v0.0.1
    github.com/dwschulze/go-module-test-stringutilmod v0.0.1
)

go 1.15

I need to use the branch dev2 for development. The godocs don't show what needs to be done to the import path or the require statement in go.mod. If I change the import statement to:

datemodlocal "192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2"

I get:

$ go run main.go
package command-line-arguments
imports 192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2: can only use path@version syntax with go get

If I move the @dev2 to the require statement in go.mod

192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2 v0.0.1

I get

$ go run main.go
go: 192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2@v0.0.1: unrecognized import path "192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2": https fetch: Get "https://192.168.0.12/gitrepo/go-module-test-dateutil.git@dev2?go-get=1": dial tcp 192.168.0.12:443: connect: connection refused

That error message says https which is strange since in my ~/.gitconfig I have

[url "dean@192.168.0.12:"] insteadOf = https://192.168.0.12/

Setting GOPRIVATE has no effect. If I put the @dev2 in both places I get the same error messages.

The godocs don't show any examples of what a working .go and go.mod file would have to contain to use modules on a branch other than master. I would think that modules would have to work on any branch because development is often done on branches other than master.

Does anyone have a working example of a .go file and a go.mod that work on a branch other than master?

Dean Schulze
  • 9,633
  • 24
  • 100
  • 165
  • 2
    Does this answer your question? [How to get another branch instead of default branch with go get](https://stackoverflow.com/questions/42761820/how-to-get-another-branch-instead-of-default-branch-with-go-get) – alessiosavi Sep 21 '20 at 22:47
  • I would recommend a different, much saner and safer approach: If you want to develop against a certain commit C of a repo R: Check out C of R locally on your file system and use a `replace` directive to map a dependency to your local version. That is what replace directives are for. The whole idea of a "branch dependency" is flawed as a branch is nothing stable you can depend on. – Volker Sep 22 '20 at 06:26
  • 1
    @Volker or just `fork` the branch - and you know the code will never disappear. – colm.anseo Sep 22 '20 at 12:35
  • @colm.anseo Forking Go packages is trivial in the simple case and astonishingly hard in the general case. Advising to fork a Go package is a very bad advise. – Volker Sep 22 '20 at 13:04
  • 1
    @Volker please expand on this. For legacy packages (no commits in +years) it makes perfect sense. – colm.anseo Sep 22 '20 at 13:36
  • @colm.anseo From a business-continuity perspective it makes sense and I did not argue against it. I said it can become technically very challenging because naive "forking" a package might break it (e.g. if the package does introspection via reflection on its own name). The simple cases are trivial but not all cases are trivial and requires deep knowledge and might introduce subtle bugs. Doable? Yes! Sensible from a business perspective? Yes! Should be recommended? No because doing it right is complicated. – Volker Sep 22 '20 at 13:49
  • 1
    @Volker - You're probably thinking of something different. I'm doing development on a non-master branch. You say branches are unstable, but that is because code is being committed. That's normal. You are going to be doing development on one branch or another. It often isn't the master branch, though. What you refer to as a commit C is also known as a tag. That is how Go modules do semantic versioning. Go modules, if they worked correctly on non-master branches save you the problem of checking out a particular commit by instead using a tag. – Dean Schulze Sep 22 '20 at 23:17
  • @DeanSchulze No, I'm thinking of your use case. My wording might have been bad, sorry. Note that `go get` of a branch does not automatically "follow" that branch. Each `go get` of that branch will just get the last commit of that branch so if you want to do "development against this branch" you have to constantly `go get` this branch and my advise is to not `go get` the branch but add a replace directive to a local checkout of this branch and `git pull`ing there constantly as this is a much clearer setup. – Volker Sep 23 '20 at 06:11
  • @DeanSchulze Go's module and dependency management have no notion of a SNAPSHOT dependency or however this type of dependency might be called in the tooling you are familiar with. Go's dependencies are exact and deterministic. The way you want to work is possible and done through a `replace` directive to a local copy of that dependency. How this local dependency evolves is not a concern of the Go tooling, it is up to you. Explicitly naming a commit in my first was didactically bad. Sorry for that. I'll add an answer. – Volker Sep 23 '20 at 06:17

2 Answers2

0

As far as I found, It is not possible to use branch name in Golang Modules(go.mod).
Instead, use git hash.

go get -u github.com/your/repo@{git-hash}
godpeny
  • 1
  • 2
-4

Go's tooling has no notion of a SNAPSHOT or development or moving dependency. Dependencies are fixed and trying to circumvent this by go geting a branch will lead to more problems.

If you have a moving dependency:

  1. Add a replace directive to go.mod making this dependency point to a local copy of it.
  2. Manage that local copy of the dependency the way you want, e.g. by checking out a certain branch and git pulling regularly.

If you have an Go-unusable git server:

If you have a VCS server which doesn't provide meta tags as described in https://golang.org/pkg/cmd/go/#hdr-Remote_import_paths you must use a replace directive and manage the local copy manually with your VCS.

In any case: An import path of the form "192.168.0.12/gitrepo/go-module-test-stringutil.git" (with a .git suffix) is wrong as explained in https://golang.org/pkg/cmd/go/#hdr-Remote_import_paths: The ".git" should go to "192.168.0.12/gitrepo.git/go-module-test-stringutil" if "gitrepo" actually is the repo.

Volker
  • 40,468
  • 7
  • 81
  • 87
  • 1
    I have no idea what you are talking about here. I want to use Go modules as they are designed but I my git repo doesn't have a web server and is on a private IP address. Development will be done on branches that are non-master and that is where the problem comes in. – Dean Schulze Sep 23 '20 at 21:20
  • @DeanSchulze You say you want to use Go modules the way they are designed but you are trying to do everything completely different: Using import paths ending in .git, using a git server which does not support remote import paths (see https://golang.org/pkg/cmd/go/#hdr-Remote_import_paths), having moving dependencies and not wanting to use replace directives. – Volker Sep 24 '20 at 05:51
  • @DeanSchulze A private IP address of your git is not the problem, a import like "192.168.0.12/gitrepo/go-module-test-dateutil" would be perfectly fine. And using a replace directive is _the_ designed way of using a package in a "non-taged" version, typically during development. And it is the _only_ way to make a dependency available if your git server doesn't speak https://golang.org/pkg/cmd/go/#hdr-Remote_import_paths (which yours seems not to support). – Volker Sep 24 '20 at 05:57