{"thread":{"id":"22533","subject":"How can I tell if a file has been updated upstream?","startedAt":"2010-02-05T16:23:11Z","lastAt":"2010-02-26T00:18:51Z","messageCount":7,"participants":["Timur Tabi","Shawn O. Pearce","Junio C Hamano","Nicolas Pitre"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"133690","messageId":"ed82fe3e1002050823gec57827j184c9c4cff4f4a45@mail.gmail.com","threadId":"22533","inReplyTo":null,"subject":"How can I tell if a file has been updated upstream?","fromName":"Timur Tabi","fromEmail":"timur@freescale.com","sentAt":"2010-02-05T16:23:11Z","receivedAt":"2010-02-05T16:23:11Z","isPatch":false,"sender":{"key":"timur@freescale.com","avatar":null},"body":"Is there a way for me to tell if a particular file in my repository\nhas an update in the upstream repository?  For example, the SHA of the\nHEAD is different in the remote repository than it is of the HEAD in\nthe local repository.\n\nThe reason I ask is that I have a set of Python scripts that I\ndistribute via git (other people in the company clone my repository).\nI want my script, every time it's run, to check if an update is\navailable, and ask the user to do \"git pull\".\n\n-- \nTimur Tabi\nLinux kernel developer at Freescale\n"},{"id":"133691","messageId":"20100205164407.GA27498@spearce.org","threadId":"22533","inReplyTo":"ed82fe3e1002050823gec57827j184c9c4cff4f4a45@mail.gmail.com","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2010-02-05T16:44:07Z","receivedAt":"2010-02-05T16:44:07Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Timur Tabi <timur@freescale.com> wrote:\n> Is there a way for me to tell if a particular file in my repository\n> has an update in the upstream repository?  For example, the SHA of the\n> HEAD is different in the remote repository than it is of the HEAD in\n> the local repository.\n> \n> The reason I ask is that I have a set of Python scripts that I\n> distribute via git (other people in the company clone my repository).\n> I want my script, every time it's run, to check if an update is\n> available, and ask the user to do \"git pull\".\n\nYou can't tell a particular file, but you could use something like\n`git ls-remote refs/heads/master` to see what the branch is at,\nand compare that to the last known commit.  If its changed, then\nsuggest the user do a fetch.\n\nI do this in repo, only I run `git fetch` once per day for the\nend-user.  That way the objects are local, and I can use a local\ncheck to see if there are updates that need to be pulled into the\nexecutable working directory.\n\n-- \nShawn.\n"},{"id":"133692","messageId":"7vk4urbp9u.fsf@alter.siamese.dyndns.org","threadId":"22533","inReplyTo":"ed82fe3e1002050823gec57827j184c9c4cff4f4a45@mail.gmail.com","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-05T16:50:21Z","receivedAt":"2010-02-05T16:50:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Timur Tabi <timur@freescale.com> writes:\n\n> The reason I ask is that I have a set of Python scripts that I\n> distribute via git (other people in the company clone my repository).\n> I want my script, every time it's run, to check if an update is\n> available, and ask the user to do \"git pull\".\n\nSo whenever I run your script it calls home, spend a roundtrip time, and\nnags me to update?  I don't want to be working with you unless I can go\nwithout running that script less often than once a week ;-)\n\nYou need to teach it how to call home.  How do your users \"clone\"?  Some\nover git://, some others over ssh://, yet some others over local\nfilesystem?  Also how do they run the script?  Directly out of the\nrepository work tree, or is there a \"make install\" step involved?\n\nIf your users are running from the work tree copy unmodified, then you\nwould need to look at sys.argv[0] to find out where it is, use that to\nfind the repository, and using its .git/config learn how the user pulls\nfrom your repository (i.e. git config remote.origin.url), and at the same\ntime which version it is (i.e. git rev-parse HEAD).  If \"make install\" is\ninvolved, then you would hardcode the necessary information during the\nbuild process to the script your users would run.\n\nAt runtime, you would run \"ls-remote HEAD\" and compare with the version\nyou are running.  It may be stale, or it may not be.\n\nHow big is the script?  It _might_ be faster to distribute a launcher that\ndownloads the real script every time it runs and runs that fresh copy that\nis guaranteed to be the latest than doing all the hassle of the above.\n"},{"id":"133693","messageId":"ed82fe3e1002050856v68d4d02bnbe18394bebac2f4d@mail.gmail.com","threadId":"22533","inReplyTo":"20100205164407.GA27498@spearce.org","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Timur Tabi","fromEmail":"timur@freescale.com","sentAt":"2010-02-05T16:56:56Z","receivedAt":"2010-02-05T16:56:56Z","isPatch":false,"sender":{"key":"timur@freescale.com","avatar":null},"body":"On Fri, Feb 5, 2010 at 10:44 AM, Shawn O. Pearce <spearce@spearce.org> wrote:\n\n> You can't tell a particular file, but you could use something like\n> `git ls-remote refs/heads/master` to see what the branch is at,\n\n$ git ls-remote refs/heads/master\nfatal: 'refs/heads/master' does not appear to be a git repository\nfatal: The remote end hung up unexpectedly\n\nSo maybe you meant this:\n\n$ git ls-remote ssh://git.am.freescale.net/git/timur/bin refs/heads/master\n20fbe12069038057cbd0d66c5a673956f7792c7d\trefs/heads/master\n\nI can use this to compare with the local HEAD.  However, this only\ntells me that the repository as a whole has changed.  I was hoping\nthere would be a way to see if just the one file has change.  I.e. how\ncan I get the HEAD of a *file* in a remote repository.\n\n> I do this in repo, only I run `git fetch` once per day for the\n> end-user.  That way the objects are local, and I can use a local\n> check to see if there are updates that need to be pulled into the\n> executable working directory.\n\nYeah, I'm not keen on performing an actual download, even if it's just a fetch.\n\n-- \nTimur Tabi\nLinux kernel developer at Freescale\n"},{"id":"133694","messageId":"ed82fe3e1002050857h300de908n5f3e4497c9ec2460@mail.gmail.com","threadId":"22533","inReplyTo":"7vk4urbp9u.fsf@alter.siamese.dyndns.org","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Timur Tabi","fromEmail":"timur@freescale.com","sentAt":"2010-02-05T16:57:47Z","receivedAt":"2010-02-05T16:57:47Z","isPatch":false,"sender":{"key":"timur@freescale.com","avatar":null},"body":"On Fri, Feb 5, 2010 at 10:50 AM, Junio C Hamano <gitster@pobox.com> wrote:\n\n> So whenever I run your script it calls home, spend a roundtrip time, and\n> nags me to update?\n\nYes.  Fortunately, it's all on an internal network, so the overhead is low.\n\n> I don't want to be working with you unless I can go\n> without running that script less often than once a week ;-)\n\nThat's about how often most people will run the script.\n\n> You need to teach it how to call home.  How do your users \"clone\"?\n\ngit clone git://....\n\nOnly I have ssh access to my repository.\n\n> Also how do they run the script?  Directly out of the\n> repository work tree, or is there a \"make install\" step involved?\n\nDirectly out of the repository.  It's just a Python script.\n\n> If your users are running from the work tree copy unmodified, then you\n> would need to look at sys.argv[0] to find out where it is, use that to\n> find the repository, and using its .git/config learn how the user pulls\n> from your repository (i.e. git config remote.origin.url), and at the same\n> time which version it is (i.e. git rev-parse HEAD).\n\nOk.\n\n> At runtime, you would run \"ls-remote HEAD\" and compare with the version\n> you are running.  It may be stale, or it may not be.\n\nOk.\n\n> How big is the script?  It _might_ be faster to distribute a launcher that\n> downloads the real script every time it runs and runs that fresh copy that\n> is guaranteed to be the latest than doing all the hassle of the above.\n\nI don't want to force an update, and I don't want to have to email\neveryone whenever there is an update.   This seems to be the least\nintrusive approach.\n\n-- \nTimur Tabi\nLinux kernel developer at Freescale\n"},{"id":"133699","messageId":"alpine.LFD.2.00.1002051235000.1681@xanadu.home","threadId":"22533","inReplyTo":"ed82fe3e1002050856v68d4d02bnbe18394bebac2f4d@mail.gmail.com","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-02-05T17:39:18Z","receivedAt":"2010-02-05T17:39:18Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 5 Feb 2010, Timur Tabi wrote:\n\n> So maybe you meant this:\n> \n> $ git ls-remote ssh://git.am.freescale.net/git/timur/bin refs/heads/master\n> 20fbe12069038057cbd0d66c5a673956f7792c7d\trefs/heads/master\n> \n> I can use this to compare with the local HEAD.  However, this only\n> tells me that the repository as a whole has changed.  I was hoping\n> there would be a way to see if just the one file has change.  I.e. how\n> can I get the HEAD of a *file* in a remote repository.\n\nYou can't.\n\nYou must perform a fetch and then use whatever method to compare with \norigin/master:foobar.py which is the file you're looking for.\n\n> Yeah, I'm not keen on performing an actual download, even if it's just a fetch.\n\nWhy?  It is not like if a fetch was terribly more costly than any method \nthat could get the version of a file on the remote.\n\n\nNicolas\n"},{"id":"135709","messageId":"ed82fe3e1002251618g750764bm82b0653770554dcf@mail.gmail.com","threadId":"22533","inReplyTo":"ed82fe3e1002050823gec57827j184c9c4cff4f4a45@mail.gmail.com","subject":"Re: How can I tell if a file has been updated upstream?","fromName":"Timur Tabi","fromEmail":"timur@freescale.com","sentAt":"2010-02-26T00:18:51Z","receivedAt":"2010-02-26T00:18:51Z","isPatch":false,"sender":{"key":"timur@freescale.com","avatar":null},"body":"On Fri, Feb 5, 2010 at 10:23 AM, Timur Tabi <timur@freescale.com> wrote:\n> Is there a way for me to tell if a particular file in my repository\n> has an update in the upstream repository?\n\nThanks to everyone who replied.  Here's what I came up with:\n\ndef check_for_updates():\n    # Get the path to our script.  This should be a git repository.\n    script_path = os.path.dirname(os.path.realpath(__file__))\n\n    # Determine the upstream URL\n    p = subprocess.Popen(['git', 'config', '-f', script_path + '/.git/config',\n        '--get', 'remote.origin.url'],\n        shell=False, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))\n    url = p.communicate()[0].strip()\n    if not url:\n        # The script is not running from a git repository\n        return\n\n    # Determine the HEAD of the upstream repository\n    p = subprocess.Popen(['git', 'ls-remote', url, 'HEAD'],\n        shell=False, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))\n    sha = p.communicate()[0].split()\n    if not sha:\n        # Something is wrong with the upstream repository\n        return\n    sha = sha[0] # The SHA of the upstream head\n\n    # Check if the remote SHA is in the local repository.\n    # git --git-dir=/home/b04825/bin/.git show-ref HEAD\n    p = subprocess.Popen(['git', '--git-dir=' + script_path + '/.git',\n        'log', '-1', sha],\n        shell=False, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'))\n    if not p.communicate()[0]:\n        # If we can't find the SHA locally, then it means that the local\n        # repository is out of date.  We pretend that it means that this script\n        # is out of date.\n        print 'There is an update for this script available.  Please\npull from the remote'\n        print 'repository (e.g. \"cd %s; git pull\")' % script_path\n\n-- \nTimur Tabi\nLinux kernel developer at Freescale\n"}]}