Scopri il ramo di un commit appartiene al LibGit2Sharp?
-
13-11-2019 - |
Domanda
Io sono un ciclo si impegna in LibGit2Sharp
:
Repository repo = new Repository("Z:/www/gg");
foreach (LibGit2Sharp.Commit commit in repo.Commits)
{
...
}
Posso recuperare le proprietà come Author
e Message
, ma non vedo nulla di quello che ramo appartiene?Idealmente mi piacerebbe avere un puntatore al ramo oggetto, ma anche un nome che sarebbe stato bene in questo scenario.
Questo è ciò che il debugger si presenta:
Questo è quello che sto cercando:
TortoiseGit comportamento di mostrare più rilevanti filiale di nome:
Esempio repository: https://docs.google.com/open?id=0B-3-X85VysdNcmZIaGVTSDZSenVGbTJxYlI2SUlsZw
Soluzione
Attualmente non c'è un modo per imitare git branch --contains <commit>
.
Tuttavia, è possibile aggirare questo limite esplicitamente a piedi ogni ramo e confrontando ogni spuntato commettere contro cercati uno.
Test riportato di seguito viene illustrato questo
[Test]
public void CanSearchBranchesContainingASpecificCommit()
{
using (var repo = new Repository(StandardTestRepoPath))
{
const string commitSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644";
IEnumerable<Branch> branches = ListBranchesContaininingCommit(repo, commitSha);
branches.Count().ShouldEqual(6);
}
}
private IEnumerable<Branch> ListBranchesContaininingCommit(Repository repo, string commitSha)
{
foreach (var branch in repo.Branches)
{
var commits = repo.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha);
if (!commits.Any())
{
continue;
}
yield return branch;
}
}
Nota: Questo codice è stato testato con successo contro l'attuale punta del ramo di sviluppo di LibGit2Sharp.
AGGIORNAMENTO:
Dopo la discussione nei commenti, ecco un piccolo aggiornamento, che spero di soddisfare la vostra richiesta.
Il codice riportato di seguito restituisce tutti i rami contenenti cercato di commit.Se il commit capita di essere la punta di almeno un ramo, quei rami verrà invece restituito.
[Test]
public void CanSearchBranchesContainingASpecificCommit()
{
using (var repo = new Repository(StandardTestRepoPath))
{
const string commitSha = "5b5b025afb0b4c913b4c338a42934a3863bf3644";
IEnumerable<Branch> branches = ListBranchesContaininingCommit(repo, commitSha);
branches.Count().ShouldEqual(6);
const string otherCommitSha = "4a202b346bb0fb0db7eff3cffeb3c70babbd2045";
branches = ListBranchesContaininingCommit(repo, otherCommitSha);
branches.Count().ShouldEqual(1); // origin/packed-test
}
}
private IEnumerable<Branch> ListBranchesContaininingCommit(Repository repo, string commitSha)
{
bool directBranchHasBeenFound = false;
foreach (var branch in repo.Branches)
{
if (branch.Tip.Sha != commitSha)
{
continue;
}
directBranchHasBeenFound = true;
yield return branch;
}
if (directBranchHasBeenFound)
{
yield break;
}
foreach (var branch in repo.Branches)
{
var commits = repo.Commits.QueryBy(new CommitFilter { Since = branch }).Where(c => c.Sha == commitSha);
if (!commits.Any())
{
continue;
}
yield return branch;
}
}
Altri suggerimenti
Git non memorizza le informazioni sulla filiale con commit. Dovresti camminare sul DAG della storia e vedere se il commit è raggiungibile dagli arbitri.
Sulla linea di comando con il normale git si eseguiresti git branch --contains $SHA1
Come ha detto Knittl, Git non memorizza tali informazioni. Un commit è uno stato fisso del repository con alcuni metadati. Poiché un commit è immutabile e a quali rami appartiene possono cambiare, le informazioni sulla filiale non possono essere archiviate direttamente nel commit.
Quindi, per scoprire se un certo commit appartiene effettivamente a qualche filiale, devi camminare attraverso gli commit di quella filiale e confrontarli con il commit.
Per renderlo più veloce, puoi archiviare tutti gli commit per ogni filiale in un HashSet<T>
come questo:
var branchCommits =
repo.Branches.Select(
b => new
{
b.Name,
Commits = new HashSet<Commit>(b.Commits)
})
.ToArray();
foreach (Commit commit in branch.Commits)
{
var commitBranches = branchCommits.Where(b => b.Commits.Contains(commit));
…
}