From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by sourceware.org (Postfix) with ESMTPS id 5504D385E01B for ; Fri, 27 Mar 2020 15:28:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5504D385E01B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wr1-x444.google.com with SMTP id h9so11863372wrc.8 for ; Fri, 27 Mar 2020 08:28:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=UJokMQfwKnojeYt64P2wGLzJAEgdxGZ4SRSn9ExG2iE=; b=c+RCdKsv1Tw/t/xmsYGSX7VyBnF0lf2oph++hGS04rMfVV2BPQuzkrvK8rOZKNOTKk aAwKAUYkcLy6Y7D4Ae/8U16l9CtbfTqlYhlBX9K9AOAQzL/4LuHHDb1ECAmyDlYWYqjx MwrkIzEWLN2jawkUGo+p6LSEJWi14ncBNDYS+aRdvyWFypiqDGuERsSg+BgNSTfZCn8B 89QscZ90hLn1bnqvOjVRKfT36G0qD4HrfvNwoqTKKXb7sXiExckIgLIjXTMy6dzmfx8g HOnQvWJwYyOQnXM6BW+FT/v4GvU1dR6hcgiBeJrIgh6ctOXPCwUM3B5x6Str9rN840kN sSlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=UJokMQfwKnojeYt64P2wGLzJAEgdxGZ4SRSn9ExG2iE=; b=kaJEwmv9wzutY65sIQLjrb2Oto3j+pVeQMtggEMHqVsDnI94j9l9u4DrTDeCj0DDnt lpvO4Bn7VQMpT8Y2TFob74a/b1lZqihUoWnnL/jSrl3tZA3VWm+/aMeocQ3lSxGnoq6N /DGmnxPJPU7uLfIowTCkwNmK8JEOvayy2TkZhacgLlSwnJQdblvX6tVs+iFvAQIdqZ1z ojMD0C/peUg4ancb5zi52qyyrNRfEYwEwswzVEbpJdbQG6hdKUmo5Dc48HJwcQkC+ZBO Os46QAwyUpIu29mJ5eoVcFeLNUOg3laekejjQXMxYlIr7WXelKlJUHzc5GwWl/G9Fs8/ 1UaA== X-Gm-Message-State: ANhLgQ0nfyCZ5NV+2iwn/zhPyQY9LuHcUHEj8xXg7Fg8fYR+p6ho6p3Z TIjl45jcdoj8IC0Th3NRfXJX1bP5KvM= X-Google-Smtp-Source: ADFU+vtaBTxLnE++DB4TrsS70G80SvTArUHdqy4v3ORuIyfZXn9tLCpb775TGsJyDEcW9Hg48RPXAA== X-Received: by 2002:adf:ab5a:: with SMTP id r26mr4999194wrc.313.1585322916184; Fri, 27 Mar 2020 08:28:36 -0700 (PDT) Received: from localhost (host86-186-80-207.range86-186.btcentralplus.com. [86.186.80.207]) by smtp.gmail.com with ESMTPSA id y16sm8680245wrp.78.2020.03.27.08.28.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 27 Mar 2020 08:28:35 -0700 (PDT) Date: Fri, 27 Mar 2020 15:28:34 +0000 From: Andrew Burgess To: Simon Marchi Cc: gdb-patches@sourceware.org, Joel Brobecker Subject: Re: [PATCH 2/2] Add git sha information to the gdb version string Message-ID: <20200327152834.GC587@embecosm.com> References: <16599d81be47851f9ce53d7da037d9a1cdeba490.1585311874.git.andrew.burgess@embecosm.com> <0b4bb502-4632-207c-cae6-94eeecb85f32@simark.ca> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <0b4bb502-4632-207c-cae6-94eeecb85f32@simark.ca> X-Operating-System: Linux/4.18.19-100.fc27.x86_64 (x86_64) X-Uptime: 15:24:46 up 42 days, 2:53, X-Fortune: Genius is the talent of a person who is dead. X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] User-Agent: Mutt/1.9.2 (2017-12-15) X-Spam-Status: No, score=-26.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Mar 2020 15:28:40 -0000 * Simon Marchi [2020-03-27 09:56:35 -0400]: > On 2020-03-27 8:27 a.m., Andrew Burgess wrote: > > + > > + # Use the remote url pattern from the remote-repository file to > > + # find the local name for the remote git repository. > > + remote_name=$( (cd "$srcdir" && git remote -v) \ > > + | grep "${remote_repo_pattern}" | grep \(fetch\) \ > > + | awk -F '\t' '{print $1}') > > I just tried it locally, this is what I get: > > GNU gdb (GDB) 10.0.50.20200327-git (c13ff238f921--0) > > I identifier the problem to the fact that I have two remotes that match the given > URL: > > $ git remote -v | grep 'sourceware.org/git/binutils-gdb.git' > origin git://sourceware.org/git/binutils-gdb.git (fetch) > origin git://sourceware.org/git/binutils-gdb.git (push) > upstream ssh://sourceware.org/git/binutils-gdb.git (fetch) > upstream ssh://sourceware.org/git/binutils-gdb.git (push) OK. I hadn't considered that. But challenge accepted :) The new version should handle multiple remotes and identify the most up to date and use that one. If try the version below and do 'git remote rename origin zzzzz', then we should still find and use the zzzzz remote. I've done a bit of basic testing but more exposure would be great. Thanks, Andrew --- commit f5f1136f1549720f38d904016ded68e0b70bc99b Author: Andrew Burgess Date: Mon Mar 9 10:17:46 2020 +0000 Add git sha information to the gdb version string Adds information about the precise git version from which gdb was built. The new version string will look like this: GNU gdb (GDB) 10.0.50.20200307-git (137acc6fbd6-72fbdf834da-2-dirty) The first half (up to the '-git' string) is as before, and taken from the version.in file within the gdb source tree, with the date text taken from the bfd source tree. The second part is new, and is built from the current git version. This is broken down like this: 137acc6fbd6-72fbdf834da-2-dirty | | | | | | | '---A-----' '-----B---' C '-D-' Where: A - This is the last git commit sha. This represents the HEAD of the branch that was built. B - This is the merge base between the current branch and the upstream master branch. C - The number of commits from the merge base to the current sha. This gives an impression of how diverged the branch is. D - Is the current git tree fully committed? If not then it is dirty. Parts B, C, and D are optional, though B and C will almost always appear together (see below for details). The following are all valid: 137acc6fbd6-72fbdf834da-2-dirty Current HEAD is 137acc6fbd6, which is 2 commits from the merge-base 72fbdf834da (which is in sourceware's master branch), however, the repository that built this GDB was not fully committed, so 137acc6fbd6 will not accurately represent the source code that built this GDB. 137acc6fbd6-72fbdf834da-2 Like the above, but the repository was fully committed, so 137acc6fbd6 does exactly match the source code that built this version of GDB. 72fbdf834da-dirty This version of GDB was built directly from sourceware's master branch (commit 72fbdf834da), however the repository had local changes at the time of build, so 72fbdf834da does not exactly match the source code that built this version of GDB. 72fbdf834da Like the above, but the repository was clean at the time of build, so 72fbdf834da exactly matches that source code that built this version of GDB. 137acc6fbd6-unknown-dirty 137acc6fbd6-unknown These occur when the version script can't find the remote sourceware repository, and so is unable to figure out a suitable merge-base, nor can the script figure out if the current HEAD is in sourceware's master branch. In this case parts B and C are replaced with the string 'unknown'. I have tried to ensure that if the source code is not a git repository then the git version token will not be added, so folks building from tar files should get exactly what they had before. The file gdbsupport/remote-repository contains the pattern used to identify the remote repository, and the name of the upstream branch from that repository which we care about. For us this will be sourceware and master, but by moving these strings into a separate file anyone maintaining an out of tree GDB can easily update these to point to their repository and branch, and get project specific version strings. gdbsupport/ChangeLog: * create-version.sh: Add git sha information. * remote-repository: New file. gdbserver/ChangeLog: * Makefile.in (version-generated.cc): Add remote-repository file as a dependency. gdb/ChangeLog: * Makefile.in (stamp-version): Add remote-repository file as a dependency. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index bc3ef695bbd..92a88f6d7e7 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2071,7 +2071,7 @@ $(srcdir)/copying.c: @MAINTAINER_MODE_TRUE@ $(srcdir)/../COPYING3 $(srcdir)/copy version.c: stamp-version; @true # Note that the obvious names for the temp file are taken by # create-version.sh. -stamp-version: Makefile version.in $(srcdir)/../bfd/version.h $(srcdir)/../gdbsupport/create-version.sh +stamp-version: Makefile version.in $(srcdir)/../bfd/version.h $(srcdir)/../gdbsupport/create-version.sh $(srcdir)/../gdbsupport/remote-repository $(ECHO_GEN) $(SHELL) $(srcdir)/../gdbsupport/create-version.sh $(srcdir) \ $(host_alias) $(target_alias) version-t.t @$(SHELL) $(srcdir)/../move-if-change version-t.t version.c diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 37e38611d5d..b52d6bccf95 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2020-03-27 Andrew Burgess + + * Makefile.in (version-generated.cc): Add remote-repository file + as a dependency. + 2020-03-20 Simon Marchi * config.in: Re-generate. diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in index 8c35c169d62..0c67d64b02e 100644 --- a/gdbserver/Makefile.in +++ b/gdbserver/Makefile.in @@ -445,7 +445,7 @@ am--refresh: force: -version-generated.cc: Makefile $(srcdir)/../gdb/version.in $(srcdir)/../bfd/version.h $(srcdir)/../gdbsupport/create-version.sh +version-generated.cc: Makefile $(srcdir)/../gdb/version.in $(srcdir)/../bfd/version.h $(srcdir)/../gdbsupport/create-version.sh $(srcdir)/../gdbsupport/remote-repository $(ECHO_GEN) $(SHELL) $(srcdir)/../gdbsupport/create-version.sh $(srcdir)/../gdb \ $(host_alias) $(target_alias) $@ diff --git a/gdbsupport/ChangeLog b/gdbsupport/ChangeLog index 1d27971f5cc..1323894b407 100644 --- a/gdbsupport/ChangeLog +++ b/gdbsupport/ChangeLog @@ -1,3 +1,8 @@ +2020-03-27 Andrew Burgess + + * create-version.sh: Add git sha information. + * remote-repository: New file. + 2020-03-27 Andrew Burgess * create-version.sh: Resolve issues highlighted by shellcheck. diff --git a/gdbsupport/create-version.sh b/gdbsupport/create-version.sh index 6135d219d94..52c8dc959d5 100755 --- a/gdbsupport/create-version.sh +++ b/gdbsupport/create-version.sh @@ -27,9 +27,182 @@ host_alias="$2" target_alias="$3" output="$4" +# Takes two parameters extracted from the remote-repository file. The first +# is the pattern for the remote repository, and the second is the name of +# the remote branch to use. +find_remote_name () +{ + remote_repo_pattern=$1 + remote_repo_branch=$2 + + # Use the remote url pattern from the remote-repository file to + # find the local name for the remote git repository. It might be + # that the user has multiple remotes all pointing at the same + # remote repository. + remote_names=$( (cd "$srcdir" && git remote -v) \ + | grep "${remote_repo_pattern}" | grep \(fetch\) \ + | awk -F '\t' '{print $1}') + + # How many remotes did we find? + remote_count=$(echo "$remote_names" | wc -l) + + # If we only found 0 or 1 remotes then we know what to do. + if [ "$remote_count" = 0 ]; then + echo "" + return + elif [ "$remote_count" = 1 ]; then + echo "$remote_names" + return + fi + + # This user has multiple remotes all pointing at the upstream + # repository. We want to find the most up to date remote, and return + # its name. We don't worry about efficiency here, we assume that there + # will only be a couple of remote names pointing at the same remote url. + while IFS= read -r remote1; do + is_best=yes + branch1="$remote1/$remote_repo_branch" + + # Check that this remote can give us a head sha. No point trying to + # use a remote that's just broken. + if ! (cd "$srcdir" && git rev-parse --short "$branch1" \ + >/dev/null 2>/dev/null ); then + continue + fi + + # Compare REMOTE1 agaist every other remote. + while IFS= read -r remote2; do + if [ "$remote1" != "$remote2" ]; then + branch2="$remote2/$remote_repo_branch" + + # Again, check that REMOTE2 isn't just broken. + if ! (cd "$srcdir" && git rev-parse --short "$branch2" \ + >/dev/null 2>/dev/null ); then + continue + fi + + # If REMOTE2 is not an ancestor of REMOTE1 then REMOTE2 must + # have more recent commits than REMOTE1, so REMOTE1 is not + # the best choice. Two remotes pointing at the same commit + # are both ancestors of each other. + if ! (cd "$srcdir" && git merge-base \ + --is-ancestor "$branch2" \ + "$branch1"); then + is_best=no + fi + fi + done </dev/null 2>/dev/null); then + + # The git version string looks something like this: + # + # 137acc6fbd6-72fbdf834da-2-dirty + # | | | | | | | + # '---A-----' '-----B---' C '-D-' + # + # Where: + # A - This is the last git commit sha. This represents the HEAD of the + # branch that was built. + # B - This is the merge base between the current branch and the + # upstream master branch. + # C - The number of commits from the merge base to the current sha. + # This gives an impression of how diverged the branch is. + # D - Is the current git tree fully committed? If not then it is dirty. + # + # First figure out part A, the short sha for the current head: + short_head_sha=$(cd "$srcdir" && git rev-parse --short HEAD) + + # Now figure out part D, the dirty tag. This might be left as the + # empty string if the repository has no local changes. + dirty_mark="" + (cd "$srcdir" && git update-index -q --refresh) + test -z "$(cd "$srcdir" && git diff-index --name-only HEAD --)" || + dirty_mark="-dirty" + + # To calculate parts B and C we need to calculate the merge-base + # between the current branch and a specific remote branch. The + # local file 'remote-repository' contains the remote repository + # url, and the branch name we are comparing against. Here we + # extract that information. + remote_repo_pattern=$(grep ^pattern: \ + "$srcdir/../gdbsupport/remote-repository" \ + | cut -d: -f2-) + remote_repo_branch=$(grep ^branch: \ + "$srcdir/../gdbsupport/remote-repository" \ + | cut -d: -f2-) + + # Use the remote url pattern from the remote-repository file to + # find the local name for the remote git repository. + remote_name=$( find_remote_name "${remote_repo_pattern}" "${remote_repo_branch}" ) + branch_info="" + if [ -n "${remote_name}" ]; then + # We found the local name for the remote repository, we can + # now go ahead and figure out parts B and C of the version + # string. + remote_branch="${remote_name}/${remote_repo_branch}" + # Check to see if the remote branch contains the current HEAD. + # If it does then the user is building directly from (their + # checkout of) the upstream branch. + if ! (cd "$srcdir" && git merge-base \ + --is-ancestor "${short_head_sha}" \ + "${remote_branch}"); then + # The current head sha is not on the remote tracking + # branch. We need to figure out the merge base, and the + # distance from that merge base. + merge_base_sha=$(cd "$srcdir" && git merge-base "${short_head_sha}" \ + "${remote_branch}") + short_merge_base_sha=$(cd "$srcdir" \ + && git rev-parse \ + --short "${merge_base_sha}") + + # Count the commits between the merge base and current head. + commit_count=$(cd "$srcdir" \ + && git rev-list --count "${merge_base_sha}"..HEAD) + + # Now format the parts B and C of the git version string. + branch_info="-${short_merge_base_sha}-${commit_count}" + else + # The user is building from a commit on the upstream + # branch. There's no need to include parts B and C of the + # git version string. + branch_info="" + fi + else + # We couldn't find the local name for the remote repository. + # Maybe this user has cloned from some other remote, or has + # deleted their remotes. + branch_info="-unknown" + fi + GIT_TAG="${short_head_sha}${branch_info}${dirty_mark}" +fi + rm -f version.c-tmp "$output" version.tmp date=$(sed -n -e 's/^.* BFD_VERSION_DATE \(.*\)$/\1/p' "$srcdir/../bfd/version.h") sed -e "s/DATE/$date/" < "$srcdir/version.in" > version.tmp +if [ -n "$GIT_TAG" ]; then + echo " ($GIT_TAG)" >> version.tmp +fi { echo '#include "gdbsupport/version.h"' echo 'const char version[] = "'"$(sed q version.tmp)"'";' diff --git a/gdbsupport/remote-repository b/gdbsupport/remote-repository new file mode 100644 index 00000000000..c05f3163e81 --- /dev/null +++ b/gdbsupport/remote-repository @@ -0,0 +1,2 @@ +pattern:sourceware.org/git/binutils-gdb.git +branch:master