Example #1
0
        public IEnumerable <SearchResult> Search(SearchQuery query, FileManager fileManager)
        {
            var repos = from dir in fileManager.DirectoryInfo.EnumerateDirectories()
                        let repoInfo = GitUtilities.GetRepoInfo(dir.FullName)
                                       where repoInfo.IsGitRepo
                                       select repoInfo;

            foreach (var repo in repos)
            {
                if (query.Terms.All(t => repo.Name.IndexOf(t, StringComparison.OrdinalIgnoreCase) != -1 || repo.Description.IndexOf(t, StringComparison.OrdinalIgnoreCase) != -1))
                {
                    yield return(new SearchResult
                    {
                        LinkText = repo.Name,
                        ActionName = "ViewRepo",
                        ControllerName = "Browse",
                        RouteValues = new { repo = repo.Name },
                        Lines = new List <SearchLine>
                        {
                            new SearchLine {
                                Line = repo.Description
                            },
                        },
                    });
                }
            }
        }
Example #2
0
        public ActionResult ViewRepo(string repo)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            var repoInfo = GitUtilities.GetRepoInfo(resourceInfo.FullPath);

            if (!repoInfo.IsGitRepo)
            {
                return(HttpNotFound());
            }

            AddRepoBreadCrumb(repo);

            var lastCommit = GitUtilities.GetLogEntries(resourceInfo.FullPath, 1).FirstOrDefault();

            ViewBag.RepoInfo    = GitUtilities.GetRepoInfo(resourceInfo.FullPath);
            ViewBag.LastCommit  = lastCommit;
            ViewBag.CurrentTree = lastCommit != null?GitUtilities.GetTreeInfo(resourceInfo.FullPath, "HEAD") : null;

            ViewBag.Refs = GitUtilities.GetAllRefs(resourceInfo.FullPath);

            return(View());
        }
        private IEnumerable <SearchResult> Search(SearchQuery query, RepoInfo repo, bool includeRepoName = false)
        {
            var allTerms      = string.Join(" --or ", query.Terms.Select(t => "-e " + GitUtilities.Q(t)));
            var commandResult = GitUtilities.Execute("grep --line-number --fixed-strings --ignore-case --context 3 --null --all-match " + allTerms + " HEAD", repo.RepoPath);

            var repoResults = commandResult.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

            return(from m in repoResults
                   where m != "--"
                   where !m.StartsWith("Binary file")
                   let parts = m.Split('\0')
                               let filePath = parts[0].Split(':')[1]
                                              let searchLine = new SearchLine
            {
                Line = parts[2],
                LineNumber = int.Parse(parts[1]),
            }
                   group searchLine by filePath into g
                   select new SearchResult
            {
                LinkText = (includeRepoName ? repo.Name + " " : string.Empty) + "/" + g.Key,
                ActionName = "ViewBlob",
                ControllerName = "Browse",
                RouteValues = new { repo = repo.Name, @object = "HEAD", path = g.Key },
                Lines = g.ToList(),
            });
        }
Example #4
0
        public ActionResult ViewCommit(string repo, string @object)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Browse", "ViewCommit", @object, new { repo, @object });

            var commit = GitUtilities.GetLogEntries(resourceInfo.FullPath, 1, 0, @object).FirstOrDefault();

            if (commit == null)
            {
                return(HttpNotFound());
            }

            var diffs = GitUtilities.GetDiffInfo(resourceInfo.FullPath, commit.Parents.FirstOrDefault() ?? GitUtilities.EmptyTreeHash, commit.CommitHash);

            ViewBag.RepoName       = resourceInfo.Name;
            ViewBag.CommitLogEntry = commit;

            return(View(diffs));
        }
Example #5
0
        public ActionResult GetInfoRefs(string url)
        {
            var service      = this.GetService();
            var resourceInfo = this.FileManager.GetResourceInfo(url);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                var repoPath = ((FileInfo)resourceInfo.FileSystemInfo).Directory.Parent.FullName;
                GitUtilities.UpdateServerInfo(repoPath);

                if (resourceInfo.Type == ResourceType.NotFound)
                {
                    resourceInfo = this.FileManager.GetResourceInfo(url);
                }
            }

            if (service == null || resourceInfo.Type == ResourceType.Directory)
            {
                return(this.Fetch(url));
            }
            else
            {
                var repoPath = ((FileInfo)resourceInfo.FileSystemInfo).Directory.Parent.FullName;

                return(new GitCommandResult("{0} --stateless-rpc --advertise-refs .", service, repoPath));
            }
        }
Example #6
0
        public ActionResult ViewTree(string repo, string @object, string path)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            TreeView items;

            try
            {
                items = GitUtilities.GetTreeInfo(resourceInfo.FullPath, @object, path);
            }
            catch (GitErrorException)
            {
                return(HttpNotFound());
            }

            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Browse", "ViewTree", @object, new { repo, @object, path = string.Empty });
            this.BreadCrumbs.Append("Browse", "ViewTree", BreadCrumbTrail.EnumeratePath(path), p => p.Key, p => new { repo, @object, path = p.Value });

            ViewBag.RepoName = resourceInfo.Name;
            ViewBag.Tree     = @object;
            ViewBag.Path     = path ?? string.Empty;

            return(View(items));
        }
Example #7
0
        public ActionResult ViewGraph(string repo, int page = 1)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory || page < 1)
            {
                return(HttpNotFound());
            }

            const int PageSize = 50;
            int       skip     = PageSize * (page - 1);
            var       count    = GitUtilities.CountCommits(resourceInfo.FullPath, allRefs: true);

            if (skip >= count)
            {
                return(HttpNotFound());
            }

            this.BreadCrumbs.Append("Browse", "Index", "Browse");
            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Graph", "ViewGraph", "View Graph", new { repo });

            var commits = GetLogEntries(resourceInfo.FullPath, skip + PageSize).Skip(skip).ToList();

            ViewBag.PaginationInfo = new PaginationInfo(page, (count + PageSize - 1) / PageSize, "Graph", "ViewGraph", new { repo });
            ViewBag.RepoName       = resourceInfo.Name;

            return(View(commits));
        }
Example #8
0
        public ActionResult ManageRepo(string repoName, RepoSettings settings)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repoName);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            var repo = GitUtilities.GetRepoInfo(resourceInfo.FullPath);

            if (!repo.IsGitRepo)
            {
                return(HttpNotFound());
            }

            if (!ModelState.IsValid)
            {
                return(View(settings));
            }

            io::File.WriteAllText(Path.Combine(resourceInfo.FullPath, "description"), settings.Description);
            if (repo.IsArchived != settings.IsArchived)
            {
                GitUtilities.ToggleArchived(resourceInfo.FullPath);
            }

            return(RedirectToAction("ViewRepo", "Browse", new { repo = repoName }));
        }
Example #9
0
        public ActionResult ViewCommits(string repo, string @object = null, int page = 1)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory || page < 1)
            {
                return(HttpNotFound());
            }

            const int PageSize = 20;
            int       skip     = PageSize * (page - 1);
            var       count    = GitUtilities.CountCommits(resourceInfo.FullPath, @object);

            if (skip >= count)
            {
                return(HttpNotFound());
            }

            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Browse", "ViewCommits", "Commit Log", new { repo, @object });

            var commits  = GitUtilities.GetLogEntries(resourceInfo.FullPath, PageSize, skip, @object);
            var branches = GitUtilities.GetAllRefs(resourceInfo.FullPath).Where(r => r.RefType == RefType.Branch).ToList();

            ViewBag.PaginationInfo = new PaginationInfo(page, (count + PageSize - 1) / PageSize, "Browse", "ViewCommits", new { repo });
            ViewBag.RepoName       = resourceInfo.Name;
            ViewBag.Object         = @object ?? "HEAD";
            ViewBag.Branches       = branches;

            return(View(commits));
        }
Example #10
0
        public ActionResult Index(bool archived = false)
        {
            var directory = this.FileManager.DirectoryInfo;

            ViewBag.Archived = archived;
            var repos = (from dir in directory.EnumerateDirectories()
                         select GitUtilities.GetRepoInfo(dir.FullName)).Where(ri => ri.IsArchived == archived).ToList();

            return(View(repos));
        }
Example #11
0
        public IEnumerable <SearchResult> Search(SearchQuery query, FileManager fileManager)
        {
            var repos = from dir in fileManager.DirectoryInfo.EnumerateDirectories()
                        let repoInfo = GitUtilities.GetRepoInfo(dir.FullName)
                                       where repoInfo.IsGitRepo
                                       select repoInfo;

            return(from repo in repos
                   from searchResult in Search(query, repo, includeRepoName: true)
                   select searchResult);
        }
        public ActionResult LastCommits()
        {
            var directory = this.FileManager.DirectoryInfo;

            var items = from repo in directory.EnumerateDirectories()
                        from entry in GitUtilities.GetLogEntries(repo.FullName, 1)
                        select FormatLogEntry(entry, repo.Name);

            var feed = BuildFeed("Last Commit in All Repos", items);

            return(new AtomActionResult(feed));
        }
Example #13
0
        public override void ExecuteResult(ControllerContext context)
        {
            var response = context.HttpContext.Response;

            var commandResult = GitUtilities.Execute(string.Format(this.commandFormat, this.service), this.workingDir);
            var commandData   = GitUtilities.DefaultEncoding.GetBytes(commandResult);

            response.StatusCode  = 200;
            response.ContentType = "application/x-git-" + this.service + "-advertisement";
            response.BinaryWrite(PacketFormat(string.Format("# service=git-{0}\n", this.service)));
            response.BinaryWrite(PacketFlush());
            response.BinaryWrite(commandData);
        }
Example #14
0
        public ActionResult Create(CreateRepoRequest request)
        {
            string repoPath = null;

            if (ModelState.IsValid)
            {
                var invalid = Path.GetInvalidFileNameChars();

                if (request.RepoName.Any(c => invalid.Contains(c)))
                {
                    ModelState.AddModelError("RepoName", "Repository name must be a valid folder name.");
                }
                else
                {
                    var resourceInfo = this.FileManager.GetResourceInfo(request.RepoName);

                    if (resourceInfo.FileSystemInfo == null)
                    {
                        ModelState.AddModelError("RepoName", "You do not have permission to create this repository.");
                    }

                    if (resourceInfo.Type != ResourceType.NotFound)
                    {
                        ModelState.AddModelError("RepoName", "There is already an object at that location.");
                    }

                    repoPath = resourceInfo.FullPath;
                }
            }

            if (!ModelState.IsValid)
            {
                return(View(request));
            }

            try
            {
                GitUtilities.CreateRepo(repoPath);
            }
            catch (GitErrorException ex)
            {
                ModelState.AddModelError(string.Empty, ex.Message);
                return(View(request));
            }

            io::File.WriteAllText(Path.Combine(repoPath, "description"), request.Description);

            GitUtilities.ExecutePostCreateHook(repoPath);

            return(RedirectToAction("ViewRepo", "Browse", new { repo = request.RepoName }));
        }
        public ActionResult Commits(string repo)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            var items = from entry in GitUtilities.GetLogEntries(resourceInfo.FullPath, 20)
                        select FormatLogEntry(entry, repo);

            var feed = BuildFeed(repo + " Commits", items);

            return(new AtomActionResult(feed));
        }
Example #16
0
        public ActionResult ViewRepoImpact(string repo)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            this.BreadCrumbs.Append("Browse", "Index", "Browse");
            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Impact", "ViewRepoImpact", "Impact", new { repo });

            var userImpacts = GitUtilities.GetUserImpacts(resourceInfo.FullPath);

            var allTimeImpacts = (from g in userImpacts.GroupBy(u => u.Author, StringComparer.InvariantCultureIgnoreCase)
                                  select new UserImpact
            {
                Author = g.Key,
                Commits = g.Sum(ui => ui.Commits),
                Insertions = g.Sum(ui => ui.Insertions),
                Deletions = g.Sum(ui => ui.Deletions),
                Impact = g.Sum(ui => ui.Impact),
            }).OrderByDescending(i => i.Commits);

            var weeklyImpacts = (from u in userImpacts
                                 let dayOffset = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - u.Date.DayOfWeek
                                                 let commitWeek = u.Date.Date.AddDays(dayOffset + (dayOffset > 0 ? -7 : 0))
                                                                  group u by commitWeek into wk
                                                                  select new ImpactWeek
            {
                Week = wk.Key,
                Impacts = (from g in wk.GroupBy(u => u.Author, StringComparer.InvariantCultureIgnoreCase)
                           select new UserImpact
                {
                    Author = g.Key,
                    Commits = g.Sum(ui => ui.Commits),
                    Insertions = g.Sum(ui => ui.Insertions),
                    Deletions = g.Sum(ui => ui.Deletions),
                    Impact = g.Sum(ui => ui.Impact),
                }).OrderByDescending(i => i.Commits).ToList()
            }).OrderBy(wk => wk.Week);

            ViewBag.AllTime = allTimeImpacts;
            ViewBag.Weekly  = weeklyImpacts;
            return(View());
        }
Example #17
0
        public ActionResult SearchRepo(string repo, string q)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            var repoInfo = GitUtilities.GetRepoInfo(resourceInfo.FullPath);

            if (!repoInfo.IsGitRepo)
            {
                return(HttpNotFound());
            }

            return(Search(q, repoInfo));
        }
Example #18
0
        public ActionResult ManageRepo(string repoName)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repoName);

            if (resourceInfo.Type != ResourceType.Directory)
            {
                return(HttpNotFound());
            }

            var repo = GitUtilities.GetRepoInfo(resourceInfo.FullPath);

            if (!repo.IsGitRepo)
            {
                return(HttpNotFound());
            }

            return(View(new RepoSettings
            {
                Description = repo.Description,
                IsArchived = repo.IsArchived,
            }));
        }
Example #19
0
        public override void ExecuteResult(ControllerContext context)
        {
            var response = context.HttpContext.Response;
            var request  = context.HttpContext.Request;

            response.ContentType = this.contentType;
            response.AddHeader("Content-disposition", "attachment");
            response.Buffer       = false;
            response.BufferOutput = false;

            using (var git = GitUtilities.StartGetBlob(this.repoPath, this.tree, this.path))
            {
                var writeBuffer = new char[4194304];
                int writeCount;
                while ((writeCount = git.StandardOutput.ReadBlock(writeBuffer, 0, writeBuffer.Length)) > 0)
                {
                    var bytes = GitUtilities.DefaultEncoding.GetBytes(writeBuffer, 0, writeCount);
                    response.BinaryWrite(bytes);
                }

                git.WaitForExit();
            }
        }
Example #20
0
        public List <GraphEntry> GetLogEntries(string path, int count)
        {
            var nodeColors  = new Dictionary <string, int>();
            var colorNumber = 0;

            var entries = GitUtilities.GetLogEntries(path, count + 1000, allRefs: true);
            var refs    = GitUtilities.GetAllRefs(path);

            var results = new List <GraphEntry>();

            var incoming = new List <string>();

            foreach (var entry in entries.Take(count))
            {
                var color = ColorNode(entry, nodeColors, ref colorNumber);

                results.Add(new GraphEntry
                {
                    LogEntry = entry,
                    Refs     = refs.Where(r => r.ShaId == entry.CommitHash).ToList(),

                    Node = new NodeInfo {
                        Hash = entry.CommitHash, Color = color
                    },
                    IncomingNodes = incoming.Select(i => new NodeInfo {
                        Hash = i, Color = nodeColors[i]
                    }).ToList(),
                    ParentNodes = entry.Parents.Select(i => new NodeInfo {
                        Hash = i, Color = nodeColors[i]
                    }).ToList(),
                });

                incoming = BuildOutgoing(incoming, entry);
            }

            return(results);
        }
Example #21
0
        public override void ExecuteResult(ControllerContext context)
        {
            var response    = context.HttpContext.Response;
            var request     = context.HttpContext.Request;
            var realRequest = System.Web.HttpContext.Current.Request;

            response.ContentType  = "application/x-git-" + this.action + "-result";
            response.BufferOutput = false;

            using (var git = GitUtilities.Start(string.Format(this.commandFormat, this.action), this.repoPath, redirectInput: true))
            {
                var readThread = new Thread(() =>
                {
                    var readBuffer = new byte[4096];
                    int readCount;

                    Stream wrapperStream = null;
                    try
                    {
                        var input = realRequest.GetBufferlessInputStream(disableMaxRequestLength: true);
                        if (request.Headers["Content-Encoding"] == "gzip")
                        {
                            input = wrapperStream = new GZipStream(input, CompressionMode.Decompress);
                        }

                        while ((readCount = input.Read(readBuffer, 0, readBuffer.Length)) > 0)
                        {
                            git.StandardInput.BaseStream.Write(readBuffer, 0, readCount);
                        }
                    }
                    finally
                    {
                        if (wrapperStream != null)
                        {
                            wrapperStream.Dispose();
                        }
                    }

                    git.StandardInput.Close();
                });
                readThread.Start();

                var    writeBuffer = new byte[4096];
                int    writeCount;
                byte[] copy = null;

                while ((writeCount = git.StandardOutput.BaseStream.Read(writeBuffer, 0, writeBuffer.Length)) > 0)
                {
                    if (copy == null || copy.Length != writeCount)
                    {
                        copy = new byte[writeCount];
                    }

                    for (int i = 0; i < writeCount; i++)
                    {
                        copy[i] = writeBuffer[i];
                    }

                    response.BinaryWrite(copy);
                }

                readThread.Join();
                git.WaitForExit();
            }
        }
Example #22
0
        public ActionResult ViewBlob(string repo, string @object, string path, bool raw = false)
        {
            var resourceInfo = this.FileManager.GetResourceInfo(repo);

            if (resourceInfo.Type != ResourceType.Directory || string.IsNullOrEmpty(path))
            {
                return(HttpNotFound());
            }

            var fileName       = Path.GetFileName(path);
            var containingPath = path.Substring(0, path.Length - fileName.Length);

            TreeView items;

            try
            {
                items = GitUtilities.GetTreeInfo(resourceInfo.FullPath, @object, containingPath);
            }
            catch (GitErrorException)
            {
                return(HttpNotFound());
            }

            if (!items.Objects.Any(o => o.Name == fileName))
            {
                return(HttpNotFound());
            }

            var contentType = MimeUtilities.GetMimeType(fileName);

            if (raw)
            {
                return(new GitFileResult(resourceInfo.FullPath, @object, path, contentType));
            }

            AddRepoBreadCrumb(repo);
            this.BreadCrumbs.Append("Browse", "ViewTree", @object, new { repo, @object, path = string.Empty });
            var paths = BreadCrumbTrail.EnumeratePath(path, TrailingSlashBehavior.LeaveOffLastTrailingSlash).ToList();

            this.BreadCrumbs.Append("Browse", "ViewTree", paths.Take(paths.Count() - 1), p => p.Key, p => new { repo, @object, path = p.Value });
            this.BreadCrumbs.Append("Browse", "ViewBlob", paths.Last().Key, new { repo, @object, path = paths.Last().Value });

            ViewBag.RepoName    = resourceInfo.Name;
            ViewBag.Tree        = @object;
            ViewBag.Path        = path;
            ViewBag.FileName    = fileName;
            ViewBag.ContentType = contentType;
            string model = null;

            if (contentType.StartsWith("text/") || contentType == "application/xml" || Regex.IsMatch(contentType, @"^application/.*\+xml$"))
            {
                using (var blob = GitUtilities.GetBlob(resourceInfo.FullPath, @object, path))
                {
                    using (var reader = new StreamReader(blob, detectEncodingFromByteOrderMarks: true))
                    {
                        model = reader.ReadToEnd();
                    }
                }
            }

            return(View((object)model));
        }
Example #23
0
        private IEnumerable <SearchResult> Search(SearchQuery query, RepoInfo repo, bool includeRepoName = false)
        {
            TreeView tree;

            try
            {
                tree = GitUtilities.GetTreeInfo(repo.RepoPath, "HEAD", recurse: true);
            }
            catch (GitErrorException)
            {
                yield break;
            }

            foreach (var item in tree.Objects)
            {
                var name = item.Name.Substring(item.Name.LastIndexOf('/') + 1);

                if (query.Terms.All(t => name.IndexOf(t, StringComparison.OrdinalIgnoreCase) != -1))
                {
                    var linkText = (includeRepoName ? repo.Name + " " : string.Empty) + "/" + item.Name;

                    switch (item.ObjectType)
                    {
                    case ObjectType.Tree:
                        yield return(new SearchResult
                        {
                            LinkText = linkText + "/",
                            ActionName = "ViewTree",
                            ControllerName = "Browse",
                            RouteValues = new { repo = repo.Name, @object = tree.Tree, path = tree.Path + item.Name + "/" },
                            Lines = new List <SearchLine>(),
                        });

                        break;

                    case ObjectType.Blob:
                        yield return(new SearchResult
                        {
                            LinkText = linkText,
                            ActionName = "ViewBlob",
                            ControllerName = "Browse",
                            RouteValues = new { repo = repo.Name, @object = tree.Tree, path = tree.Path + item.Name },
                            Lines = new List <SearchLine>(),
                        });

                        break;

                    case ObjectType.Commit:
                        yield return(new SearchResult
                        {
                            LinkText = linkText + "/",
                            ActionName = "ViewTree",
                            ControllerName = "Browse",
                            RouteValues = new { repo = repo.Name, @object = tree.Tree, path = tree.Path + item.Name + "/" },
                            Lines = new List <SearchLine>(),
                        });

                        break;
                    }
                }
            }
        }