From c2336062d441f4d5c3dd9169872f5209bc6d5860 Mon Sep 17 00:00:00 2001 From: Pablo Kang and Sufyan Adam Date: Wed, 12 Aug 2015 12:18:45 -0700 Subject: [PATCH] Add support for a pre-smart-pull hook User can create and executable script in .git/hooks/smart-pull-pre-fetch that will be executed just before a fetch. Example: There are tags in remote that need to be cleaned out. One team member cleans them out but then they come back the next time someone else pushes a local tag before syncing local tags to remote. A solution to this problem is to create a smart-pull-pre-fetch hook that syncs local tags to remote tags, so that old tags previously deleted on remote don't come back. --- lib/commands/smart-pull.rb | 3 +++ lib/git-smart/git_repo.rb | 8 ++++++++ spec/smart-pull_spec.rb | 15 +++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/lib/commands/smart-pull.rb b/lib/commands/smart-pull.rb index cf0423d..09ffa7a 100644 --- a/lib/commands/smart-pull.rb +++ b/lib/commands/smart-pull.rb @@ -21,6 +21,9 @@ note("No tracking remote configured, assuming 'origin'") || 'origin' + # Run smart-pull-pre-fetch hook + repo.run_hook('smart-pull-pre-fetch') + # Fetch the remote. This pulls down all new commits from the server, not just our branch, # but generally that's a good thing. This is the only communication we need to do with the server. repo.fetch!(tracking_remote) diff --git a/lib/git-smart/git_repo.rb b/lib/git-smart/git_repo.rb index 7df60c8..6ab5ec1 100644 --- a/lib/git-smart/git_repo.rb +++ b/lib/git-smart/git_repo.rb @@ -59,6 +59,14 @@ def tracking_branch end end + def run_hook(hook_file) + full_path = File.join(git_dir, 'hooks', hook_file) + if File.exists?(full_path) + output = SafeShell.execute(full_path) + $?.success? ? puts(output) : raise(GitSmart::UnexpectedOutput.new(output)) + end + end + def fetch!(remote) git!('fetch', remote) end diff --git a/spec/smart-pull_spec.rb b/spec/smart-pull_spec.rb index 63c5c30..0034a56 100644 --- a/spec/smart-pull_spec.rb +++ b/spec/smart-pull_spec.rb @@ -36,6 +36,21 @@ def remote_dir; WORKING_DIR + '/remote'; end out.should report("Already up-to-date") end + context "with a smart-pull-pre-fetch hook" do + before :each do + %x[ + cd #{local_dir} + printf '#!/bin/bash\n\necho running hook...done\n' > .git/hooks/smart-pull-pre-fetch + chmod 755 .git/hooks/smart-pull-pre-fetch + ] + end + + it "should run the hook" do + out = run_command(local_dir, 'smart-pull') + out.should report("running hook...done") + end + end + context "with only local changes" do before :each do %x[