Skip to content
Permalink
Browse files

GitWorkingTree: First try to use the pull remote of the current branch

Git supports multiple remotes per working tree. Previously, simply the
first remote in the order reported by Git was used, but this is not
necessarily the remote that we want. We are interested in where the code
in the working tree comes from, so first try to use the remote that the
currently checked out branch pulls from, and only afterwards fall back
to "origin", if present, or the first other remote.

Signed-off-by: Sebastian Schuberth <sebastian.schuberth@bosch-si.com>
  • Loading branch information...
sschuberth committed Oct 7, 2019
1 parent 920ce20 commit 7de18ea7ecd78c574d0c4a4d80e98cedd0143246
Showing with 19 additions and 3 deletions.
  1. +19 −3 downloader/src/main/kotlin/vcs/GitWorkingTree.kt
@@ -25,6 +25,8 @@ import com.here.ort.utils.ProcessCapture

import java.io.File

private const val GIT_STATUS_BRANCH_UPSTREAM_PREFIX = "# branch.upstream "

open class GitWorkingTree(workingDir: File, private val gitBase: GitBase) : WorkingTree(workingDir, gitBase.type) {
override fun isValid(): Boolean {
if (!workingDir.isDirectory) {
@@ -49,7 +51,8 @@ open class GitWorkingTree(workingDir: File, private val gitBase: GitBase) : Work
return paths.associateWith { GitWorkingTree(root.resolve(it), gitBase).getInfo() }
}

override fun getRemoteUrl() = gitBase.run(workingDir, "remote", "get-url", getFirstRemote()).stdout.trimEnd()
override fun getRemoteUrl() =
gitBase.run(workingDir, "remote", "get-url", getRemoteForCheckout()).stdout.trimEnd()

override fun getRevision() = gitBase.run(workingDir, "rev-parse", "HEAD").stdout.trimEnd()

@@ -58,7 +61,7 @@ open class GitWorkingTree(workingDir: File, private val gitBase: GitBase) : Work

private fun listRemoteRefs(namespace: String): List<String> {
val tags = gitBase.run(workingDir, "-c", "credential.helper=", "-c", "core.askpass=echo", "ls-remote",
"--refs", getFirstRemote(), "refs/$namespace/*").stdout.trimEnd()
"--refs", getRemoteForCheckout(), "refs/$namespace/*").stdout.trimEnd()
return tags.lines().map {
it.split('\t').last().removePrefix("refs/$namespace/")
}
@@ -68,5 +71,18 @@ open class GitWorkingTree(workingDir: File, private val gitBase: GitBase) : Work

override fun listRemoteTags() = listRemoteRefs("tags")

private fun getFirstRemote() = gitBase.run(workingDir, "remote", "show", "-n").stdout.lineSequence().first()
private fun getRemoteForCheckout(): String {
// Get the remote the current branch (if any) is configured to pull from.
val status = gitBase.run(workingDir, "status", "-sb", "--porcelain=v2").stdout
status.lineSequence().find { line ->
line.startsWith(GIT_STATUS_BRANCH_UPSTREAM_PREFIX)
}?.let { upstreamBranch ->
return upstreamBranch.substringAfter(GIT_STATUS_BRANCH_UPSTREAM_PREFIX).substringBefore('/')
}

// In case we are not on a branch, fall back to listing all remotes. Prefer "origin" if present but otherwise
// return the first remote.
val remotes = gitBase.run(workingDir, "remote", "show", "-n").stdout.lines()
return remotes.find { it == "origin" } ?: remotes.first()
}
}

0 comments on commit 7de18ea

Please sign in to comment.
You can’t perform that action at this time.