From 117cad1bace9343d5e8ee64089bd0a9c9247c02b Mon Sep 17 00:00:00 2001 From: Tomas Deml Date: Fri, 7 Apr 2017 14:21:47 +0200 Subject: [PATCH] Downstream repository is checked for uncommitted changes and commits made in detached HEAD state when `update`ing/`restore`ing Git dependency Checking for uncommitted changes prevents hard-to-track bugs as well as non-repeatable builds that might occur by merging user's changes into the new working directory. Checking for detached commits makes working in the downstream repository safer - it saves the user from having to inspect reflog after "losing" her commits. It also forces the user to move the changes to a permanent branch when making meaningful changes. --- src/Paket.Core/GitHandling.fs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Paket.Core/GitHandling.fs b/src/Paket.Core/GitHandling.fs index b0ccda0476..e95ce0193b 100644 --- a/src/Paket.Core/GitHandling.fs +++ b/src/Paket.Core/GitHandling.fs @@ -158,6 +158,20 @@ let fetchCache repoCacheFolder cloneUrl = with | exn -> failwithf "Fetching the git cache at %s failed.%sMessage: %s" repoCacheFolder Environment.NewLine exn.Message +let checkForUncommittedChanges repoFolder = + try + tracefn "Checking for uncommitted changes in %s" repoFolder + CommandHelper.gitCommand repoFolder "diff-index --quiet HEAD --" |> ignore + with + | exn -> failwithf "It seems there are uncommitted changes in the repository. The changes must be committed/discarded first.%sMessage: %s" Environment.NewLine exn.Message + +let checkForCommitsMadeInDetachedHeadState repoFolder = + try + tracefn "Checking for commits made in detached HEAD state in %s" repoFolder + CommandHelper.gitCommand repoFolder "name-rev --no-undefined HEAD --" |> ignore + with + | exn -> failwithf "It seems that some commits would become unreachable after checkout. Create branch for the commits or reset them first and try again.%sMessage: %s" Environment.NewLine exn.Message + let tagCommitForCheckout repoFolder commit = try CommandHelper.runSimpleGitCommand repoFolder (sprintf "tag -f %s %s" paketCheckoutTag commit) |> ignore @@ -181,6 +195,9 @@ let checkoutToPaketFolder repoFolder cloneUrl cacheCloneUrl commit = CommandHelper.runSimpleGitCommand destination (sprintf "clone %s %s" (quote cacheCloneUrl) (quote repoFolder)) |> ignore CommandHelper.runSimpleGitCommand repoFolder (sprintf "remote set-url origin %s" <| quote cloneUrl) |> ignore + checkForUncommittedChanges repoFolder + checkForCommitsMadeInDetachedHeadState repoFolder + tracefn "Setting %s to %s" repoFolder commit tagCommitForCheckout repoFolder commit checkoutTaggedCommit repoFolder