Beispiel #1
0
        public void CanCancelRecursiveClone()
        {
            var    uri = new Uri($"file://{Path.GetFullPath(SandboxSubmoduleSmallTestRepo())}");
            var    scd = BuildSelfCleaningDirectory();
            string relativeSubmodulePath = "submodule_target_wd";

            int cancelDepth = 0;

            RepositoryOperationStarting repositoryOperationStarting = (x) =>
            {
                return(!(x.RecursionDepth >= cancelDepth));
            };

            CloneOptions options = new CloneOptions()
            {
                RecurseSubmodules           = true,
                RepositoryOperationStarting = repositoryOperationStarting,
            };

            Assert.Throws <UserCancelledException>(() =>
                                                   Repository.Clone(uri.AbsolutePath, scd.DirectoryPath, options));

            // Cancel after super repository is cloned, but before submodule is cloned.
            cancelDepth = 1;

            string clonedRepoPath = null;

            try
            {
                Repository.Clone(uri.AbsolutePath, scd.DirectoryPath, options);
            }
            catch (RecurseSubmodulesException ex)
            {
                Assert.NotNull(ex.InnerException);
                Assert.Equal(typeof(UserCancelledException), ex.InnerException.GetType());
                clonedRepoPath = ex.InitialRepositoryPath;
            }

            // Verify that the submodule was not initialized.
            using (Repository repo = new Repository(clonedRepoPath))
            {
                var submoduleStatus = repo.Submodules[relativeSubmodulePath].RetrieveStatus();
                Assert.Equal(SubmoduleStatus.InConfig | SubmoduleStatus.InHead | SubmoduleStatus.InIndex | SubmoduleStatus.WorkDirUninitialized,
                             submoduleStatus);
            }
        }
Beispiel #2
0
        public void CanRecursivelyCloneSubmodules()
        {
            var    uri = new Uri($"file://{Path.GetFullPath(SandboxSubmoduleSmallTestRepo())}");
            var    scd = BuildSelfCleaningDirectory();
            string relativeSubmodulePath = "submodule_target_wd";

            // Construct the expected URL the submodule will clone from.
            string expectedSubmoduleUrl = Path.Combine(Path.GetDirectoryName(uri.AbsolutePath), relativeSubmodulePath);

            expectedSubmoduleUrl = expectedSubmoduleUrl.Replace('\\', '/');

            Dictionary <string, CloneCallbackInfo> callbacks = new Dictionary <string, CloneCallbackInfo>();

            CloneCallbackInfo currentEntry  = null;
            bool unexpectedOrderOfCallbacks = false;

            CheckoutProgressHandler checkoutProgressHandler = (x, y, z) =>
            {
                if (currentEntry != null)
                {
                    currentEntry.CheckoutProgressCalled = true;
                }
                else
                {
                    // Should not be called if there is not a current
                    // callbackInfo entry.
                    unexpectedOrderOfCallbacks = true;
                }
            };

            UpdateTipsHandler remoteRefUpdated = (x, y, z) =>
            {
                if (currentEntry != null)
                {
                    currentEntry.RemoteRefUpdateCalled = true;
                }
                else
                {
                    // Should not be called if there is not a current
                    // callbackInfo entry.
                    unexpectedOrderOfCallbacks = true;
                }

                return(true);
            };

            RepositoryOperationStarting repositoryOperationStarting = (x) =>
            {
                if (currentEntry != null)
                {
                    // Should not be called if there is a current
                    // callbackInfo entry.
                    unexpectedOrderOfCallbacks = true;
                }

                currentEntry = new CloneCallbackInfo();
                currentEntry.StartingWorkInRepositoryCalled = true;
                currentEntry.RecursionDepth = x.RecursionDepth;
                currentEntry.RemoteUrl      = x.RemoteUrl;
                callbacks.Add(x.RepositoryPath, currentEntry);

                return(true);
            };

            RepositoryOperationCompleted repositoryOperationCompleted = (x) =>
            {
                if (currentEntry != null)
                {
                    currentEntry.FinishedWorkInRepositoryCalled = true;
                    currentEntry = null;
                }
                else
                {
                    // Should not be called if there is not a current
                    // callbackInfo entry.
                    unexpectedOrderOfCallbacks = true;
                }
            };

            CloneOptions options = new CloneOptions()
            {
                RecurseSubmodules            = true,
                OnCheckoutProgress           = checkoutProgressHandler,
                OnUpdateTips                 = remoteRefUpdated,
                RepositoryOperationStarting  = repositoryOperationStarting,
                RepositoryOperationCompleted = repositoryOperationCompleted,
            };

            string clonedRepoPath = Repository.Clone(uri.AbsolutePath, scd.DirectoryPath, options);
            string workDirPath;

            using (Repository repo = new Repository(clonedRepoPath))
            {
                workDirPath = repo.Info.WorkingDirectory.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
            }

            // Verification:
            // Verify that no callbacks were called in an unexpected order.
            Assert.False(unexpectedOrderOfCallbacks);

            Dictionary <string, CloneCallbackInfo> expectedCallbackInfo = new Dictionary <string, CloneCallbackInfo>();

            expectedCallbackInfo.Add(workDirPath, new CloneCallbackInfo()
            {
                RecursionDepth = 0,
                RemoteUrl      = uri.AbsolutePath,
                StartingWorkInRepositoryCalled = true,
                FinishedWorkInRepositoryCalled = true,
                CheckoutProgressCalled         = true,
                RemoteRefUpdateCalled          = true,
            });

            expectedCallbackInfo.Add(Path.Combine(workDirPath, relativeSubmodulePath), new CloneCallbackInfo()
            {
                RecursionDepth = 1,
                RemoteUrl      = expectedSubmoduleUrl,
                StartingWorkInRepositoryCalled = true,
                FinishedWorkInRepositoryCalled = true,
                CheckoutProgressCalled         = true,
                RemoteRefUpdateCalled          = true,
            });

            // Callbacks for each expected repository that is cloned
            foreach (KeyValuePair <string, CloneCallbackInfo> kvp in expectedCallbackInfo)
            {
                CloneCallbackInfo entry = null;
                Assert.True(callbacks.TryGetValue(kvp.Key, out entry), string.Format("{0} was not found in callbacks.", kvp.Key));

                Assert.Equal(kvp.Value.RemoteUrl, entry.RemoteUrl);
                Assert.Equal(kvp.Value.RecursionDepth, entry.RecursionDepth);
                Assert.Equal(kvp.Value.StartingWorkInRepositoryCalled, entry.StartingWorkInRepositoryCalled);
                Assert.Equal(kvp.Value.FinishedWorkInRepositoryCalled, entry.FinishedWorkInRepositoryCalled);
                Assert.Equal(kvp.Value.CheckoutProgressCalled, entry.CheckoutProgressCalled);
                Assert.Equal(kvp.Value.RemoteRefUpdateCalled, entry.RemoteRefUpdateCalled);
            }

            // Verify the state of the submodule
            using (Repository repo = new Repository(clonedRepoPath))
            {
                var sm = repo.Submodules[relativeSubmodulePath];
                Assert.True(sm.RetrieveStatus().HasFlag(SubmoduleStatus.InWorkDir |
                                                        SubmoduleStatus.InConfig |
                                                        SubmoduleStatus.InIndex |
                                                        SubmoduleStatus.InHead));

                Assert.NotNull(sm.HeadCommitId);
                Assert.Equal("480095882d281ed676fe5b863569520e54a7d5c0", sm.HeadCommitId.Sha);

                Assert.False(repo.RetrieveStatus().IsDirty);
            }
        }