Missed Team ’24? Catch up on announcements here.

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

Differences of bundled Git/Mercurial to original ones

MikeL February 21, 2013

What are the exact details of the differences between the bundled Git/Mercurial versions compared to the original ones where they derived from?

1 answer

1 accepted

0 votes
Answer accepted
stevestreeting
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 21, 2013

Git is unchanged, it's just the binary version you can download from their site at the version number listed in the Preferences > Git page.

Mercurial has had some minor patches applied to make sure things like password prompts are fully flushed even when called by something that's not a real terminal, so SourceTree can see them and respond. The full source code is included inside SourceTree (we tell you where in the About box, but for info it's SourceTree.app/Contents/Resources/mercurial_local) to comply with the GPL, and you can diff that against the source version of Mercurial to see the changes. Obviously if you diff it against the upstream source version at the version displayed in Preferences > Mercurial you'll get just the changes we made.

That's what we do to comply with the GPL, but to make it even easier, here's the 2 patch files we apply to the embedded version. The first one isolates temporary files associated with checks to a location we can identify, so they don't make ST think that files have changed and cause an unnecessary refresh to occur

diff --git a/mercurial/dirstate.py b/mercurial_local/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -113,11 +113,25 @@
 
     @propertycache
     def _checklink(self):
-        return util.checklink(self._root)
+		 # Force checks to happen in '.hgcheck' folder so we can identify them
+         d = os.path.join(self._root, '.hgcheck')
+         try:
+             if not os.path.isdir(d):
+                 os.mkdir(d)
+             return util.checklink(d)
+         except (IOError, OSError):
+             return False
 
     @propertycache
     def _checkexec(self):
-        return util.checkexec(self._root)
+		 # Force checks to happen in '.hgcheck' folder so we can identify them
+         d = os.path.join(self._root, '.hgcheck')
+         try:
+             if not os.path.isdir(d):
+                 os.mkdir(d)
+             return util.checkexec(d)
+         except (IOError, OSError):
+             return False
 
     @propertycache
     def _checkcase(self):

The second deals with flushing user/password prompts:

--- a/mercurial-2.0/mercurial/ui.py	2011-11-01 20:36:00.000000000 +0000
+++ b/mercurial/ui.py	2011-11-11 12:18:19.000000000 +0000
@@ -551,19 +551,13 @@
             except Exception:
                 pass
 
-        # call write() so output goes through subclassed implementation
-        # e.g. color extension on Windows
-        self.write(prompt)
-
-        # instead of trying to emulate raw_input, swap (self.fin,
-        # self.fout) with (sys.stdin, sys.stdout)
-        oldin = sys.stdin
-        oldout = sys.stdout
-        sys.stdin = self.fin
-        sys.stdout = self.fout
-        line = raw_input(' ')
-        sys.stdin = oldin
-        sys.stdout = oldout
+        # SourceTree mod: prompt using read_line instead which ensures prompt is flushed
+        self.write_err(prompt)
+        line = sys.stdin.readline()
+        # get rid of \r
+        line = line[:-1]
+        #line = raw_input(prompt)
+        # End SourceTree mod
 
         # When stdin is in binary mode on Windows, it can cause
         # raw_input() to emit an extra trailing carriage return
@@ -604,7 +598,16 @@
         if not self.interactive():
             return default
         try:
-            return getpass.getpass(prompt or _('password: '))
+            # Ensure we flush so that we can read prompt in non-terminal
+            self.write_err('password:')
+            pwd = sys.stdin.readline() 
+            # get rid of \r \n
+            if pwd and pwd[-1] == '\n':
+                pwd = pwd[:-1]
+            if pwd and pwd[-1] == '\r':
+                pwd = pwd[:-1]
+                
+            return pwd
         except EOFError:
             raise util.Abort(_('response expected'))
     def status(self, *msg, **opts):

FWIW, I've tried to submit these patches to Mercurial upstream a few times but never managed to get them in, that's why we continue to patch Mercurial for our use.

MikeL February 24, 2013

Thanks Steve. When I download Git 1.7.11.1 from http://git-scm.com/downloads, I only get a installer bundle. After install, /usr/local/git differs significantly from the bundled Git in Sourcetree (SourceTree.app/Contents/Resources/git_local). Do you have a different source of downloading Git?

MikeL February 27, 2013

Steve, where do you get the original Git from?

MikeL March 7, 2013

Steve, any update on this topic?

stevestreeting
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 10, 2013

Sorry for the late reply, I've been on vacation for a couple of weeks. My process for embedding git is literally this (from my own notes to remind me how to do it in fact :)

  1. Download the official binary distribution and install
  2. Copy the contents of the installed /usr/local/git folder into git_local
  3. For size reasons, remove share/git-gui, share/gitk and share/gitweb, these are not needed

Therefore I can't understand how you'd conclude the binary download is different, except maybe for the things I trimmed out to make the embedded version a little smaller. I used to have a step which stripped the 'ppc' or 'ppc7400' elements from the fat binaries, because the git binary distro used to include PowerPC support as well as i386 and Apple don't let you distribute that any more, but I haven't had to do that for a while because Git stopped packaging ppc support a year or so ago.

MikeL March 10, 2013

Thanks for the update. From where do you download the official Git binaries?

stevestreeting
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 10, 2013

Always from git-scm.com, which is why I'm confused. I don't even dig any further than the front page, just grab the latest binary from the front page link when periodically updating the embedded version.

MikeL March 20, 2013

Could the differences be caused by the digital signature of SourceTree? If so, how to remove this signature for testing purposes?

stevestreeting
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
March 20, 2013

Ah, that's very likely - we were required to sign every binary inside the .app to comply with both the App Store and the GateKeeper requirements on 10.7+ otherwise OS X wouldn't consider them valid. I'm not sure how you remove a code signature - we used the usual 'codesign' tool but I can't see an option to strip the signature back off again. It must be possible though, since nothing is recompiled when you sign the code, it just tacks on a signature that OS X can check.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events