Как изменить/удалить/добавить файлы с помощью libgit2sharp?

У меня две даты - от и до. Я должен найти файлы, измененные в репозитории между этой разницей дат, и составить их список. Вот связанный с этим вопрос, который определяет разницу между деревьями. Получить файлы, измененные/добавленные/удаленные из коммита в LibGit2Sharp.


person Murali Uppangala    schedule 17.11.2015    source источник


Ответы (2)


Итак, давайте предположим, что вы пытаетесь воспроизвести:

git log --reverse --since "11/10/2015" --until="11/15/2015" --format="%cD %s"

Когда у вас есть список коммитов, ICommitLog, через все репо Commits, отфильтрованный список веток и т. д., вы можете фильтровать через Linq.

Итак, создайте свой список коммитов:

var repo = new Repository ("/Users/sushi/code/playscript/mono");
var filter = new CommitFilter {
    SortBy = CommitSortStrategies.Time | CommitSortStrategies.Reverse,
};
var commits = repo.Commits.QueryBy(filter);

Теперь с объектом ICommitLog commits примените фильтр Linq к объектам фиксации. В этом случае я использую дату коммиттера и фильтрую коммиты от 2 до 7 дней с сегодняшнего дня, но помните, что есть также дата Author:

var since = new DateTimeOffset(DateTime.Now.AddDays(-7));
var until = new DateTimeOffset(DateTime.Now.AddDays(-2));
var filteredCommitLog = commitLog.Where(c => c.Committer.When > since && c.Committer.When < until);
foreach (Commit commit in filteredCommitLog)
{
    Console.WriteLine("{0} : {1}", commit.Committer.When.ToLocalTime(), commit.MessageShort);
}

Результаты:

11/15/2015 5:32:36 AM -08:00 : [runtime] Fix Thread.CurrentThread in non-root appdomains by setting the tls slot in start_wrapper, otherwise Thread.CurrentThread would create a new Thread object so there would be two. Fixes #35828.
11/15/2015 12:00:30 AM -08:00 : Fix a warning.
....
11/10/2015 6:41:09 AM -08:00 : Merge pull request #2214 from kumpera/fix_enum_get_get_hashcode
11/10/2015 6:07:50 AM -08:00 : [Mono.Posix] Update incorrect test

Обновление:

Я полностью пропустил часть этого ответа, список измененных файлов... :-/ (Нужно больше кофе)

git log --name-status --reverse --since "11/10/2015" --until="11/15/2015" --format="%cD %s"

Становится:

    var since = new DateTimeOffset(DateTime.Now.AddDays(-7));
    var until = new DateTimeOffset(DateTime.Now.AddDays(-2));
    var filteredCommitLog = commitLog.Where(c => c.Committer.When > since && c.Committer.When < until);
    foreach (Commit commit in filteredCommitLog)
    {
        Console.WriteLine("{0} : {1}", commit.Committer.When.ToLocalTime(), commit.MessageShort);
        foreach (var parent in commit.Parents) {
            foreach (TreeEntryChanges change in repo.Diff.Compare<TreeChanges>(parent.Tree, commit.Tree)) {
                Console.WriteLine ("\t{0} :\t{1}", change.Status, change.OldPath);
            }
        }
    }

Пример вывода:

11/11/2015 8:09:41 AM -08:00 : Crashing test in mono_class_init() from a MonoGenericClass.
    Modified :  mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs
11/11/2015 8:12:03 AM -08:00 : [runtime] mono_class_init() - don't look for metadata if the dynamic image doesn't have it.
    Modified :  mono/metadata/class.c
11/11/2015 9:05:07 AM -08:00 : Merge pull request #2217 from rcruzs00/master
    Modified :  mcs/tools/macpack/LOADER
11/11/2015 11:26:25 AM -08:00 : Merge pull request #2198 from BrzVlad/feature-concurrent-work
    Modified :  mono/sgen/sgen-conf.h
    Modified :  mono/sgen/sgen-gc.c
    Modified :  mono/sgen/sgen-memory-governor.c
    Modified :  mono/sgen/sgen-workers.c
    Modified :  mono/sgen/sgen-workers.h
    Modified :  acceptance-tests/.gitignore
    Added : acceptance-tests/GCStressTests/AssemblyExtensions.cs
    Added : acceptance-tests/GCStressTests/AssemblyLoadContext.cs
    Modified :  acceptance-tests/Makefile.am
    Modified :  acceptance-tests/SUBMODULES.json
    Modified :  acceptance-tests/versions.mk

Чтобы пропустить журнал и получить только список файлов в отфильтрованном списке фиксации:

 git log --name-status --since "11/10/2015" --until="11/15/2015" --format=""

Становится:

foreach (TreeEntryChanges change in repo.Diff.Compare<TreeChanges>(filteredCommitLog.First().Tree, filteredCommitLog.Last().Tree)) {
    Console.WriteLine ("\t{0}\t:\t{1}", change.Status, change.OldPath);
}

Пример вывода:

Modified    :   acceptance-tests/Makefile.am
Modified    :   acceptance-tests/SUBMODULES.json
Modified    :   external/referencesource
Modified    :   mcs/class/Facades/Makefile
Modified    :   mcs/class/Mono.Cairo/Mono.Cairo/Context.cs
Modified    :   mcs/class/Mono.Security/Mono.Security.Interface/CertificateValidationHelper.cs
Modified    :   mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsProvider.cs
Modified    :   mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/ActionBlockTest.cs
Modified    :   mcs/class/System.Threading.Tasks.Dataflow/Test/System.Threading.Tasks.Dataflow/BatchBlockTest.cs
Modified    :   mcs/class/System.Threading.Tasks.Data
person SushiHangover    schedule 17.11.2015
comment
я заметил нечто странное. Предположим, что между вчера и сегодня существует только одна фиксация. поэтому ваш подход сравнивает единственный коммит, существующий в этом диапазоне дат, с самим собой (первый и последний) и говорит: «Нет изменений!». Я потерял там .. нужна помощь. Что такое Treechanges? можно ли перечислить файлы из дерева или зафиксировать(ша)? @RobertN @nulltoken - person Murali Uppangala; 03.12.2015
comment
@flute Вам нужно сравнить два commish, чтобы увидеть, что изменилось, если ваш фильтр возвращает только одну фиксацию, с какой другой фиксацией вы хотите ее сравнить? Вы можете использовать родителя (ей) этой единственной фиксации, если это уместно. - person SushiHangover; 03.12.2015

Я использовал другой подход, чтобы решить эту проблему позже.

using(var repo = new Repository("c:\\_Temp\\Repo"))
{
 List<string> shalist = new List<string>();
 foreach(Commit c in repo.Commits)
 {
  DateTime since = DateTime.Parse("10/29/2015 12:00:00 AM");
  DateTime untill= c.Author.When.Date;

  if(untill >= since)
   {
     shalist.Add(c.sha.Tostring());
   }
  }

  Tree cmTree1 = repo.Lookup<Commit>(shalist.First()).Tree;  
  Tree cmTree2 = repo.Lookup<Commit>(shalist.Last()).Tree;

  var patch = repo.Diff.Compare<patch>(cmTree1, cmTree2);

  foreach(var ptc in patch)
  {
   Console.WriteLine(ptc.Path);
  }     
}

Это отобразит все файлы, измененные в диапазоне дат since - untill.

person Murali Uppangala    schedule 18.11.2015
comment
Этот подход перечислит все коммиты в вашем репозитории. Я настоятельно рекомендую вам использовать CommitFilter, предложенный @RobertN, который будет более эффективным. - person nulltoken; 18.11.2015
comment
На самом деле я обновил свой ответ, так как я полностью пропустил добавление части ответа со списком файлов, извините за это .... К вашему сведению: @nulltoken совершенно прав насчет предварительной фильтрации, если в вашем репо небольшое количество коммитов, чем нет большой проблемы , но работа с сотнями/тысячами/и т. д. коммитов, тогда предварительная фильтрация, насколько это возможно, очень поможет.... - person SushiHangover; 18.11.2015
comment
@RobertN, да, обновление хорошее! я уже внес необходимые изменения, прежде чем использовать вашу идею... она работала нормально. И да, у меня много коммитов.. так что ваш подход лучше.. - person Murali Uppangala; 19.11.2015