3

I have two dates - from and to. I have to find the files changed in the repository between that date difference and make a list of it. Here is a related question which gets the differece between trees.Get files modified/added/removed from a commit in LibGit2Sharp.

Community
  • 1
  • 1
Murali Uppangala
  • 884
  • 6
  • 22
  • 49

2 Answers2

9

So lets assume you are trying to replicate:

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

Once you have a list of commits, ICommitLog, via all the repo's Commits, a filtered branch list, etc.. you can filter via Linq.

So create your commit list:

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

Now with the ICommitLog commits object, apply a Linq filter on the commit objects. In this case I am using the committer's date and filtering the commits from 2 to 7 days from today, but remember there is also an Author date:

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);
}

Results:

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

Update:

I totally missed a part of this answer, the modified file list... :-/ (Need more coffee)

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

Becomes:

    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);
            }
        }
    }

Output example:

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

To skip the log and get only the file list within the filtered commit list:

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

Becomes:

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);
}

Example Output:

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
SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • i have noticed something strange. Suppose only one commit exist between yesterday and today. so your approach compares the the only commit exist in that date range with itself (first and last) and says "No changes!!". I lost there.. need help. What exaclty is Treechanges?. is it possible to list files from a tree or commit(sha)?@RobertN @nulltoken – Murali Uppangala Dec 03 '15 at 14:31
  • @flute You need compare two `commish` to see what changed, if your filter is only returning one commit, than what other commit do you wish to compare it to? You could use that single commit's parent(s) if that is appropriate. – SushiHangover Dec 03 '15 at 16:27
1

I did take a different approach to solve this later.

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);
  }     
}

This will display all the files changed in the date range since - untill

Murali Uppangala
  • 884
  • 6
  • 22
  • 49
  • 1
    This approach will enumerate all the commits in your repository. I'd strongly advise you to favor the usage of a `CommitFilter` as suggested by @RobertN which would be more efficient. – nulltoken Nov 18 '15 at 07:14
  • 1
    I actually updated my answer as I totally missed adding the file list part of the answer, sorry about that.... FYI: @nulltoken is totally right about pre-filtering, if your repo has a small number of commits than no big problem, but dealing with hundreds/thousands/etc.. of commits then pre-filtering as much as you can will greatly help.... – SushiHangover Nov 18 '15 at 13:30
  • @RobertN, yes, the update is good! i had already made necessary changes before using your idea..it worked fine. And yes i have a lots of commits.. so your approach is better way to go.. – Murali Uppangala Nov 19 '15 at 04:56