From 5be442daea213400a4f96c126b829257c75c35b0 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 26 Apr 2016 12:04:55 +0100 Subject: [PATCH] Add `git lfs update --manual` option & promote it on hook install fail --- commands/command_update.go | 22 ++++++++++++++++------ docs/man/git-lfs-update.1.ronn | 17 +++++++++++++++-- lfs/setup.go | 17 +++++++++++++++++ test/test-install.sh | 4 +++- test/test-update.sh | 14 +++++++++++++- 5 files changed, 64 insertions(+), 10 deletions(-) diff --git a/commands/command_update.go b/commands/command_update.go index 1da1c8db..6f67662c 100644 --- a/commands/command_update.go +++ b/commands/command_update.go @@ -14,7 +14,8 @@ var ( Run: updateCommand, } - updateForce = false + updateForce = false + updateManual = false ) // updateCommand is used for updating parts of Git LFS that reside under @@ -40,16 +41,25 @@ func updateCommand(cmd *cobra.Command, args []string) { } } - if err := lfs.InstallHooks(updateForce); err != nil { - Error(err.Error()) - Exit("Run `git lfs update --force` to overwrite this hook.") + if updateForce && updateManual { + Exit("You cannot use --force and --manual options together") + } + + if updateManual { + Print(lfs.GetHookInstallSteps()) } else { - Print("Updated pre-push hook.") + if err := lfs.InstallHooks(updateForce); err != nil { + Error(err.Error()) + Exit("To resolve this, either:\n 1: run `git lfs update --manual` for instructions on how to merge hooks.\n 2: run `git lfs update --force` to overwrite your hook.") + } else { + Print("Updated pre-push hook.") + } } } func init() { - updateCmd.Flags().BoolVarP(&updateForce, "force", "f", false, "Overwrite hooks.") + updateCmd.Flags().BoolVarP(&updateForce, "force", "f", false, "Overwrite existing hooks.") + updateCmd.Flags().BoolVarP(&updateManual, "manual", "m", false, "Print instructions for manual install.") RootCmd.AddCommand(updateCmd) } diff --git a/docs/man/git-lfs-update.1.ronn b/docs/man/git-lfs-update.1.ronn index 929425ef..a34f3c2e 100644 --- a/docs/man/git-lfs-update.1.ronn +++ b/docs/man/git-lfs-update.1.ronn @@ -3,12 +3,25 @@ git-lfs-update(1) -- Update Git hooks ## SYNOPSIS -`git lfs update` [--force] +`git lfs update` [--manual | --force] ## DESCRIPTION Updates the Git hooks used by Git LFS. Silently upgrades known hook contents. -Pass `--force` to upgrade the hooks, clobbering any existing contents. +If you have your own custom hooks you may need to use one of the extended +options below. + +## OPTIONS + +* `--manual` `-m` + Print instructions for manually updating your hooks to include git-lfs + functionality. Use this option if `git lfs update` fails because of existing + hooks and you want to retain their functionality. + +* `--force` `-f` + Forcibly overwrite any existing hooks with git-lfs hooks. Use this option + if `git lfs update` fails because of existing hooks but you don't care + about their current contents. ## SEE ALSO diff --git a/lfs/setup.go b/lfs/setup.go index 5e443a7d..6b257f11 100644 --- a/lfs/setup.go +++ b/lfs/setup.go @@ -1,5 +1,10 @@ package lfs +import ( + "bytes" + "fmt" +) + var ( // prePushHook invokes `git lfs push` at the pre-push phase. prePushHook = &Hook{ @@ -37,6 +42,18 @@ var ( } ) +// Get user-readable manual install steps for hooks +func GetHookInstallSteps() string { + + var buf bytes.Buffer + for _, h := range hooks { + buf.WriteString(fmt.Sprintf("Add the following to .git/hooks/%s :\n\n", h.Type)) + buf.WriteString(h.Contents) + buf.WriteString("\n") + } + return buf.String() +} + // InstallHooks installs all hooks in the `hooks` var. func InstallHooks(force bool) error { for _, h := range hooks { diff --git a/test/test-install.sh b/test/test-install.sh index 0f0e331c..59bf6013 100755 --- a/test/test-install.sh +++ b/test/test-install.sh @@ -75,7 +75,9 @@ Git LFS initialized." = "$(git lfs install)" ] test -Run \`git lfs update --force\` to overwrite this hook." +To resolve this, either: + 1: run \`git lfs update --manual\` for instructions on how to merge hooks. + 2: run \`git lfs update --force\` to overwrite your hook." echo "test" > .git/hooks/pre-push [ "test" = "$(cat .git/hooks/pre-push)" ] diff --git a/test/test-update.sh b/test/test-update.sh index cb9eb95b..6aa672e2 100755 --- a/test/test-update.sh +++ b/test/test-update.sh @@ -65,7 +65,9 @@ git lfs pre-push \"$@\"" test -Run \`git lfs update --force\` to overwrite this hook." +To resolve this, either: + 1: run \`git lfs update --manual\` for instructions on how to merge hooks. + 2: run \`git lfs update --force\` to overwrite your hook." [ "$expected" = "$(git lfs update 2>&1)" ] [ "test" = "$(cat .git/hooks/pre-push)" ] @@ -79,6 +81,16 @@ Run \`git lfs update --force\` to overwrite this hook." fi set -e + # test manual steps + expected="Add the following to .git/hooks/pre-push : + +#!/bin/sh +command -v git-lfs >/dev/null 2>&1 || { echo >&2 \"\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n\"; exit 2; } +git lfs pre-push \"\$@\"" + + [ "$expected" = "$(git lfs update --manual 2>&1)" ] + [ "test" = "$(cat .git/hooks/pre-push)" ] + # force replace unexpected hook [ "Updated pre-push hook." = "$(git lfs update --force)" ] [ "$pre_push_hook" = "$(cat .git/hooks/pre-push)" ]