From 84447a4662f702ab0ab4af9ba254d5e9cf7fab79 Mon Sep 17 00:00:00 2001
From: Raymond Rebbeck <raymond.rebbeck@gmail.com>
Date: Fri, 4 Oct 2024 15:25:38 +0930
Subject: [PATCH 1/4] Avoid clobbering 'command' so that it can be referred to
 later

---
 cls/SourceControl/Git/Utils.cls | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cls/SourceControl/Git/Utils.cls b/cls/SourceControl/Git/Utils.cls
index 0239f9e6..244a2191 100644
--- a/cls/SourceControl/Git/Utils.cls
+++ b/cls/SourceControl/Git/Utils.cls
@@ -1809,20 +1809,20 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
     set outLog = ##class(%Library.File).TempFilename()
     set errLog = ##class(%Library.File).TempFilename()
 
-    set command = $extract(..GitBinPath(),2,*-1)
+    set gitCommand = $extract(..GitBinPath(),2,*-1)
     
     set baseArgs = "/STDOUT="_$$$QUOTE(outLog)_" /STDERR="_$$$QUOTE(errLog)_$case(inFile, "":"", :" /STDIN="_$$$QUOTE(inFile))
     try {
         // Inject instance manager directory as global git config home directory
         // On Linux, this avoids trying to use /root/.config/git/attributes for global git config
         set env("XDG_CONFIG_HOME") = ##class(%File).ManagerDirectory()
-        set returnCode = $zf(-100,"/ENV=env... "_baseArgs,command,newArgs...)
+        set returnCode = $zf(-100,"/ENV=env... "_baseArgs,gitCommand,newArgs...)
     } catch e {
         if $$$isWINDOWS {
-            set returnCode = $zf(-100,baseArgs,command,newArgs...)
+            set returnCode = $zf(-100,baseArgs,gitCommand,newArgs...)
         } else {
             // If can't inject XDG_CONFIG_HOME (older IRIS version), need /SHELL on Linux to avoid permissions errors trying to use root's config
-            set returnCode = $zf(-100,"/SHELL "_baseArgs,command,newArgs...)
+            set returnCode = $zf(-100,"/SHELL "_baseArgs,gitCommand,newArgs...)
         }
     }
 

From 03a52c236143aed09a6579667a646669851fec8a Mon Sep 17 00:00:00 2001
From: Raymond Rebbeck <raymond.rebbeck@gmail.com>
Date: Fri, 4 Oct 2024 17:54:31 +0930
Subject: [PATCH 2/4] Add GetCurrentRevision class method

---
 cls/SourceControl/Git/Utils.cls | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/cls/SourceControl/Git/Utils.cls b/cls/SourceControl/Git/Utils.cls
index 244a2191..0ea048e2 100644
--- a/cls/SourceControl/Git/Utils.cls
+++ b/cls/SourceControl/Git/Utils.cls
@@ -447,8 +447,7 @@ ClassMethod MergeDefaultRemoteBranch(Output alert As %String = "") As %Boolean
         do ..RunGitWithArgs(.errStream, .outStream, "fetch", "origin", defaultMergeBranch_":"_defaultMergeBranch)
         do ..PrintStreams(errStream, outStream)
 
-        do ..RunGitWithArgs(,.outStream, "rev-parse", "HEAD")
-        set startSha = outStream.ReadLine()
+        set startSha = ..GetCurrentRevision()
 
         // Start a transaction so code changes can be rolled back
         set initTLevel = $TLevel
@@ -556,6 +555,13 @@ ClassMethod GetCurrentBranch() As %String
     quit branchName
 }
 
+ClassMethod GetCurrentRevision() As %String
+{
+    do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("rev-parse",,.errStream,.outStream,"HEAD")
+    set revision = outStream.ReadLine(outStream.Size)
+    quit revision
+}
+
 ClassMethod Pull(remote As %String = "origin") As %Status
 {
     New %gitSCOutputFlag

From 23b9470d92850fe724904e43ad6597ddb46698cc Mon Sep 17 00:00:00 2001
From: Raymond Rebbeck <raymond.rebbeck@gmail.com>
Date: Fri, 4 Oct 2024 18:47:14 +0930
Subject: [PATCH 3/4] When performing a pull, sync IRIS with repository changes
 using diff output rather than command output

---
 cls/SourceControl/Git/Utils.cls | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cls/SourceControl/Git/Utils.cls b/cls/SourceControl/Git/Utils.cls
index 0ea048e2..5d628c5d 100644
--- a/cls/SourceControl/Git/Utils.cls
+++ b/cls/SourceControl/Git/Utils.cls
@@ -1737,7 +1737,11 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
     } elseif (command = "restore") {
         // Leave diffCompare empty, this actually does the right thing.
         set syncIrisWithDiff = 1
-    } elseif (command = "merge") || (command = "rebase")  || (command = "pull") {
+    } elseif (command = "pull") {
+        set syncIrisWithDiff = 1
+        // The current revision, prior to the pull, will be compared against
+        set diffCompare = ..GetCurrentRevision()
+    } elseif (command = "merge") || (command = "rebase") {
         set syncIrisWithCommand = 1
         if $data(args) && $data(args(args),diffCompare) {
             // no-op
@@ -1801,7 +1805,10 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
         set syncIrisWithCommand = 0
     }
 
-    if syncIrisWithDiff {
+    // If performing a pull don't perform a diff until after the pull has occured.
+    // This is to avoid a double fetch, as pull performs one for us and also to avoid a potential
+    // race condition if the remote changes between now and the pull actually being performed.
+    if syncIrisWithDiff && (command '= "pull") {
         if diffBase = "" {
             set diffBase = ..GetCurrentBranch()
         }
@@ -1832,6 +1839,13 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
         }
     }
 
+    // If performing a pull then do a diff now after the pull has occured.
+    if syncIrisWithDiff && (command = "pull") {
+        do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("diff",,.errorStream,.outputStream, diffCompare, "--name-status")
+        // Verbose output should not be required as pull already outputs a summary
+        do ..ParseDiffStream(outputStream,0,.files)
+    }
+
     set errStream = ##class(%Stream.FileCharacter).%OpenId(errLog,,.sc)
     set outStream = ##class(%Stream.FileCharacter).%OpenId(outLog,,.sc)
     set outStream.TranslateTable="UTF8"

From da132ddab902edfae73405cabcd1b82cce8f4d5b Mon Sep 17 00:00:00 2001
From: isc-tleavitt <73311181+isc-tleavitt@users.noreply.github.com>
Date: Fri, 4 Oct 2024 13:28:30 -0400
Subject: [PATCH 4/4] chore: update CHANGELOG.md

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8cbd6d14..5bc2e2a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Fetch diff output uses correct remote branch (#509)
 - Properly handle more cases of truncated filenames from git pull (#511)
 - Made git-source-control backwards compatible with IRIS 2021.1 (#513)
+- Sync, pull properly handle more change edge cases for import (#517, #496)
 
 ## [2.5.0] - 2024-09-24