/// <summary>
        /// 'git ref-log' doesn't work if the repo is corrupted, so parsing reflogs seems like the only solution.
        /// </summary>
        /// <param name="fullSymbolicRef">A full symbolic ref name. eg. HEAD, refs/remotes/origin/HEAD, refs/heads/master</param>
        private static bool TryReadLastRefLogEntry(Enlistment enlistment, string fullSymbolicRef, out RefLogEntry refLog, out string error)
        {
            string refLogPath = Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Logs.Root, fullSymbolicRef);

            if (!File.Exists(refLogPath))
            {
                refLog = null;
                error  = "Could not find reflog for ref '" + fullSymbolicRef + "'";
                return(false);
            }

            try
            {
                string refLogContents = File.ReadLines(refLogPath).Last();
                if (!RefLogEntry.TryParse(refLogContents, out refLog))
                {
                    error = "Last ref log entry for " + fullSymbolicRef + " is unparsable.";
                    return(false);
                }
            }
            catch (IOException ex)
            {
                refLog = null;
                error  = "IOException while reading reflog '" + refLogPath + "': " + ex.Message;
                return(false);
            }

            error = null;
            return(true);
        }
示例#2
0
        public static bool TryParse(string line, out RefLogEntry entry)
        {
            entry = null;
            if (string.IsNullOrEmpty(line))
            {
                return(false);
            }

            if (line.Length < ScalarConstants.ShaStringLength + 1 + ScalarConstants.ShaStringLength)
            {
                return(false);
            }

            string sourceSha = line.Substring(0, ScalarConstants.ShaStringLength);
            string targetSha = line.Substring(ScalarConstants.ShaStringLength + 1, ScalarConstants.ShaStringLength);

            int reasonStart = line.LastIndexOf("\t");

            if (reasonStart < 0)
            {
                return(false);
            }

            string reason = line.Substring(reasonStart + 1);

            entry = new RefLogEntry(sourceSha, targetSha, reason);
            return(true);
        }
        public void FailsForNull()
        {
            string testLine = null;

            RefLogEntry output;

            RefLogEntry.TryParse(testLine, out output).ShouldEqual(false);

            output.ShouldBeNull();
        }
        public void FailsForMissingTargetSha()
        {
            const string SourceSha = "0000000000000000000000000000000000000000";
            string       testLine  = string.Format("{0} ", SourceSha);

            RefLogEntry output;

            RefLogEntry.TryParse(testLine, out output).ShouldEqual(false);

            output.ShouldBeNull();
        }
        public void FailsForMissingReason()
        {
            const string SourceSha = "0000000000000000000000000000000000000000";
            const string TargetSha = "d249e0fea84484eb105d52174cf326958ee87ab4";
            string       testLine  = string.Format("{0} {1} author <*****@*****.**> 1478738341 -0800", SourceSha, TargetSha);

            RefLogEntry output;

            RefLogEntry.TryParse(testLine, out output).ShouldEqual(false);

            output.ShouldBeNull();
        }
        public void ParsesValidRefLog()
        {
            const string SourceSha = "0000000000000000000000000000000000000000";
            const string TargetSha = "d249e0fea84484eb105d52174cf326958ee87ab4";
            const string Reason    = "clone: from https://repourl";
            string       testLine  = string.Format("{0} {1} author <*****@*****.**> 1478738341 -0800\t{2}", SourceSha, TargetSha, Reason);

            RefLogEntry output;

            RefLogEntry.TryParse(testLine, out output).ShouldEqual(true);

            output.ShouldNotBeNull();
            output.SourceSha.ShouldEqual(SourceSha);
            output.TargetSha.ShouldEqual(TargetSha);
            output.Reason.ShouldEqual(Reason);
        }