Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a previous version of a file with libgit2sharp

I'm trying to use libgit2sharp to get a previous version of a file. I would prefer the working directory to remain as is, at the very least restored to previous condition.

My initial approach was to try to stash, checkout path on the file I want, save that to a string variable, then stash pop. Is there a way to stash pop? I can't find it easily. Here's the code I have so far:

        using (var repo = new Repository(DirectoryPath, null))
        {
            var currentCommit = repo.Head.Tip.Sha;
            var commit = repo.Commits.Where(c => c.Sha == commitHash).FirstOrDefault();
            if (commit == null)
                return null;

            var sn = "Stash Name";
            var now = new DateTimeOffset(DateTime.Now);

            var diffCount = repo.Diff.Compare().Count();

            if(diffCount > 0)
                repo.Stashes.Add(new Signature(sn, "[email protected]", now), options: StashModifiers.Default);

            repo.CheckoutPaths(commit.Sha, new List<string>{ path }, CheckoutModifiers.None, null, null);
            var fileText = File.ReadAllText(path);

            repo.CheckoutPaths(currentCommit, new List<string>{path}, CheckoutModifiers.None, null, null);
            if(diffCount > 0)
                ; // stash Pop?
        }

If there's an easier approach than using Stash, that would work great also.

like image 802
Shlomo Avatar asked Aug 26 '13 18:08

Shlomo


1 Answers

Is there a way to stash pop? I can't find it easily

Unfortunately, Stash pop requires merging which isn't available yet in libgit2.

I'm trying to use libgit2sharp to get a previous version of a file. I would prefer the working directory to remain as is

You may achieve such result by opening two instances of the same repository, each of them pointing to different working directories. The Repository constructor accepts a RepositoryOptions parameter which should allow you to do just that.

The following piece of code demonstrates this feature. This creates an additional instance (otherRepo) that you can use to retrieve a different version of the file currently checked out in your main working directory.

string repoPath = "path/to/your/repo";

// Create a temp folder for a second working directory
string tempWorkDir = Path.Combine(Path.GetTempPath(), "tmp_wd");
Directory.CreateDirectory(newWorkdir);

// Also create a new index to not alter the main repository
string tempIndex = Path.Combine(Path.GetTempPath(), "tmp_idx");

var opts = new RepositoryOptions
{
    WorkingDirectoryPath = tempWorkDir,
    IndexPath = tempIndex
};

using (var mainRepo = new Repository(repoPath))
using (var otherRepo = new Repository(mainRepo.Info.Path, opts))
{
    string path = "file.txt";

    // Do your stuff with mainrepo
    mainRepo.CheckoutPaths("HEAD", new[] { path });
    var currentVersion = File.ReadAllText(Path.Combine(mainRepo.Info.WorkingDirectory, path));

    // Use otherRepo to temporarily checkout previous versions of files
    // Thank to the passed in RepositoryOptions, this checkout will not
    // alter the workdir nor the index of the main repository.
    otherRepo.CheckoutPaths("HEAD~2", new [] { path });
    var olderVersion = File.ReadAllText(Path.Combine(otherRepo.Info.WorkingDirectory, path));
}

You can get a better grasp of this RepositoryOptions type by taking a look at the tests in RepositoryOptionFixture that exercise it.

like image 52
nulltoken Avatar answered Oct 17 '22 11:10

nulltoken