Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Can I get the same information I do from "git show" through the Bitbucket Java or REST API?

Joseph Marcel March 18, 2022

What follows is three example commits.  In all cases 'git show' explains correctly, yet for merge commits the two API's give inconsistent results.

 


Consider this merge commit #1, 'git show' *correctly shows the changes to the files* (file A was developer resolved, file B was auto-merged, file C was included w/out file-level merge changes (no new revision)):

$ git show c47af8deac6b87a
commit c47af8deac6b87a35c54f750166a13089c35b770 (HEAD -> master, origin/PR2, PR2)
Merge: 4a7b7ed 705cb5f
Author: Joe
Date: Fri Mar 18 14:27:03 2022 -0400

Merge branch 'master' into PR2

diff --cc A
index bb62e45,c875e2d..695279f
--- a/A
+++ b/A
@@@ -1,3 -1,7 +1,8 @@@
adios
more stuff
+take that!
+ hello
+ what are we doing
+ this is it
+ more of the same
+ gimme a break
diff --cc B
index fecdf68,864a49b..aa01e7f
--- a/B
+++ b/B
@@@ -1,6 -1,5 +1,4 @@@
-guten tag
this is getting ridiculous
- what now?
- ho hum
goodbye
more changes
uh-oh


However the Java API shows three changes (when iterating through the changesets for that commit):

2022-03-18 19:46:16,817 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 19:46:16,817 WARN [c.o.s.r.ScriptBindingsManager]: Path: A
2022-03-18 19:46:16,817 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 19:46:16,818 WARN [c.o.s.r.ScriptBindingsManager]: Path: B
2022-03-18 19:46:16,818 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 19:46:16,818 WARN [c.o.s.r.ScriptBindingsManager]: Path: C


While the REST API shows no changes (.../commits/c47af8d/changes):

{"fromHash":null,"toHash":"c47af8d","properties":{},"values":[],"size":0,"isLastPage":true,"start":0,"limit":25,"nextPageStart":null}

 


Consider this merge commit #2, 'git show' *correctly shows that there are no changes to any files* (files A and C were included, but no new file revisions via file-level merge):

$ git show 8907e98fb71ffca612
commit 8907e98fb71ffca6120f703d0e43be4787dd173e
Merge: edb85da 2d76267
Author: Joe
Date: Thu Mar 17 12:57:40 2022 -0400

Merge branch 'master' into PR2


However the Java API shows two changes:

2022-03-18 19:53:38,354 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 19:53:38,373 WARN [c.o.s.r.ScriptBindingsManager]: Path: A
2022-03-18 19:53:38,374 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 19:53:38,374 WARN [c.o.s.r.ScriptBindingsManager]: Path: C


While the REST API shows no changes (.../commits/8907e98/changes):

{"fromHash":null,"toHash":"8907e98","properties":{},"values":[],"size":0,"isLastPage":true,"start":0,"limit":25,"nextPageStart":null}

 


For a simple (non-merge) commit, results are as expected (file A is modified):

$ git show 4a7b7ed55
commit 4a7b7ed55512a5814292ba6b1689a781c4dc225b
Author: Joe
Date: Fri Mar 18 14:24:44 2022 -0400

PR2

diff --git a/A b/A
index 76b9b5a..bb62e45 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
adios
more stuff
+take that!


2022-03-18 20:11:46,977 WARN [c.o.s.r.ScriptBindingsManager]: Type: MODIFY
2022-03-18 20:11:47,012 WARN [c.o.s.r.ScriptBindingsManager]: Path: A


{"fromHash":null,"toHash":"4a7b7ed55","properties":{},"values":[{"contentId":"bb62e451e87164abcba481ef8f73d719230e0b62","fromContentId":"76b9b5ab7d2242c33ab6ee0d9ede24233add0b66","path":{"components":["A"],"parent":"","name":"A","toString":"A"},"executable":false,"percentUnchanged":-1,"type":"MODIFY","nodeType":"FILE","srcExecutable":false,"links":{...},"properties":{"gitChangeType":"MODIFY"}}],"size":1,"isLastPage":true,"start":0,"limit":25,"nextPageStart":null}

2 answers

1 accepted

0 votes
Answer accepted
Joseph Marcel March 19, 2022
Can execute the 'git show' command from bitbucket...

// check if the commit has new file revisions
// use 'git show' and count the number of new file revisions
def outputHandler = new SingleLineOutputHandler()
gitCommandBuilderFactory.builder(commit.repository)
.command("show")
.argument("--oneline")
.argument("--name-status")
.argument(commit.id)
.build(outputHandler)
.call()
def new_file_revisions = (outputHandler.getOutput().split("\t").size()-1)
0 votes
Joseph Marcel March 19, 2022

From a top-level perspective, we've implemented a pre-receive hook to prevent pushes to master if all the files don't have review credit in Crucible...

...

def REVIEWS_PATH = 'rest-service-fe/search-v1/queryAsRows/'

commitCallback =
new PreRepositoryHookCommitCallback() {

@Override boolean onCommitAdded(@Nonnull CommitAddedDetails commitDetails) {
def commit = commitDetails.commit

// for commits on master, check to see if the commit includes file revisions
// that are part of a CLOSED review
if (commitDetails.ref.id.startsWith("refs/heads/master")) {

  // check if the commit has new file revisions
// use 'git show' and count the number of occurrences of diff output
def outputHandler = new SingleLineOutputHandler()
gitCommandBuilderFactory.builder(commit.repository)
.command("show")
.argument("--oneline")
.argument("--name-status")
.argument(commit.id)
.build(outputHandler)
.call()
def int new_file_revisions = (outputHandler.getOutput().split("\t").size()-1)

if (new_file_revisions > 0) {

// check Crucible
def REVIEWS_QUERY = URLEncoder.encode("select revisions where csid = ${commit.id} and reviewed return count(revisions)", "UTF-8")
def getReviews = authenticatedRequestFactory
.createRequest(GET, "${FISHEYE_URL}${REVIEWS_PATH}${commit.repository.name}?query=${REVIEWS_QUERY}")
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")

// {headings=[countReviews], row=[{item=[0]}]}
def result = getReviews.execute(handler)["row"]["item"][0] as ArrayList
def reviewedRevisions = result[0] as int

if (new_file_revisions == reviewedRevisions) {
// allow commits w/ reviewed revisions
return true
} else {
// the number or reviewed revisions does not match the number of new file revisions
 resultBuilder.veto("*** Unreviewed commit to master!!! ***",
"*** Commit ID: " + commit.id +
" *** New file revisions: " + new_file_revisions +
" *** Reviewed revisions: " + reviewedRevisions + " ***") return false
}

} else {
// allow commit w/ no new file revisions (likely a clean merge-commit)
return true
}

} else {
// allow non-master commits
return true
}
}

@Override RepositoryHookResult getResult() {
resultBuilder.build()
}
}

commitFilters << RepositoryHookCommitFilter.ADDED_TO_ANY_REF

return RepositoryHookResult.accepted()

 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events