EzDevInfo.com

objective-git

Objective-C bindings to libgit2

Un-stage file with libgit2

Using objective-git and libgit2 it has been fairly easy to stage a file ready for commit:

GTIndex *repoIndex = [self.repository indexWithError:&error];

[repoIndex removeFile:path error:&error];

if (status != GTFileStatusIgnored && status != GTFileStatusWorkingDeleted) {
    // Now add the file to the index
    [repoIndex addFile:path error:&error];
}

[repoIndex write:&error];

However un-staging a file is proving to be a tad more tricky. Simply removing it from the repository's index doesn't work as git then thinks the file has been deleted which makes sense. It seems what I need to do is change the index entry in the index to the one it was before it was staged.

I have tried doing the following, using diff to get the old diff delta and constructing a git_index_entry from that and inserting it:

GTIndex *repoIndex = [self.repository indexWithError:&error];
GTBranch *localBranch = [self.repository currentBranchWithError:&error];
GTCommit *localCommit = [localBranch targetCommitAndReturnError:&error];

GTDiff *indexCommitDiff = [GTDiff diffIndexFromTree:localCommit.tree inRepository:self.repository options:nil error:&error];

// Enumerate through the diff deltas until we get to the file we want to unstage
[indexCommitDiff enumerateDeltasUsingBlock:^(GTDiffDelta *delta, BOOL *stop) {

    NSString *deltaPath = delta.newFile.path;

    // Check if it matches the path we want to usntage
    if ([deltaPath isEqualToString:path]) {
        GTDiffFile *oldFile = delta.oldFile;

        NSString *oldFileSHA = oldFile.OID.SHA;
        git_oid oldFileOID;
        int status = git_oid_fromstr(&oldFileOID, oldFileSHA.fileSystemRepresentation);

        git_index_entry entry;
        entry.mode = oldFile.mode;
        entry.oid = oldFileOID;
        entry.path = oldFile.path.fileSystemRepresentation;

        [repoIndex removeFile:path error:&error];

        status = git_index_add(repoIndex.git_index, &entry);

        [repoIndex write:&error];
    }
}];

However this leaves the git index in a corrupt state resulting in any git command logging a fatal error:

fatal: Unknown index entry format bfff0000
fatal: Unknown index entry format bfff0000     

What is the correct way to un-stage a file using libgit2?


Source: (StackOverflow)

How to get list of files in repository in libgit/objective-git?

I want to get the list of files in a Git repository using objective-git, or libgit2

What I am doing now is calling the git command-line tool and parsing the output of git ls-files (or git ls-tree --name-only -r HEAD, which gives the same results), e.g.

$ git ls-files
meta/LICENSE.md
.gitignore
README.md

I would rather use a direct API provided by libgit2. I have tried objective-git’s -[GTTree enumerateContentsWithOptions:error:block:] method, but the enumerated GTTreeEntry objects only provide a name and don’t know what subdirectory they are in.


Source: (StackOverflow)

Advertisements

Include libgit2 in RubyMotion

I am trying to get objective-git included as ruby motion. I tried my best to translate the requirements on objective gits site into what is needed for an OS X ruby motion app. Here is the Rakefile, objective-git is a submodule located in vendor.

# -*- coding: utf-8 -*-
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project/template/osx'

require 'bundler/setup'
Bundler.require :default

Motion::Project::App.setup do |app|
  app.name = 'commit-zero'
  app.vendor_project 'vendor/objective-git', :xcode,
                     xcodeproj: 'vendor/objective-git/ObjectiveGitFramework.xcodeproj',
                     headers_dir: 'vendor/objective-git/External/libgit2/include'
end

Here is the error:

$ rake
     Build ./build/MacOSX-10.10-Development
Received exception: No headers to parse:
/usr/bin/gen_bridge_metadata:980:in `prepare'
/usr/bin/gen_bridge_metadata:776:in `parse'
/Library/RubyMotion/bin/gen_bridge_metadata:118:in `block in <main>'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/optparse.rb:885:in `initialize'
/Library/RubyMotion/bin/gen_bridge_metadata:38:in `new'
/Library/RubyMotion/bin/gen_bridge_metadata:38:in `<main>'
No headers to parse
Usage: gen_bridge_metadata [options] <headers...>
Use the `-h' flag or consult gen_bridge_metadata(1) for help.
rake aborted!
Command failed with status (1): [RUBYOPT='' '/Library/RubyMotion/bin/gen_br...]
/Library/RubyMotion/lib/motion/project/xcode_config.rb:366:in `gen_bridge_metadata'
/Library/RubyMotion/lib/motion/project/vendor.rb:221:in `block in build_xcode'
/Library/RubyMotion/lib/motion/project/vendor.rb:153:in `chdir'
/Library/RubyMotion/lib/motion/project/vendor.rb:153:in `build_xcode'
/Library/RubyMotion/lib/motion/project/vendor.rb:44:in `build'
/Library/RubyMotion/lib/motion/project/builder.rb:67:in `block in build'
/Library/RubyMotion/lib/motion/project/builder.rb:66:in `each'
/Library/RubyMotion/lib/motion/project/builder.rb:66:in `build'
/Library/RubyMotion/lib/motion/project/app.rb:78:in `build'
/Library/RubyMotion/lib/motion/project/template/osx.rb:41:in `block (2 levels) in <top (required)>'
/Library/RubyMotion/lib/motion/project/template/osx.rb:59:in `block in <top (required)>'
Tasks: TOP => build:development
(See full trace by running task with --trace)

Source: (StackOverflow)

Pull (fetch & merge) with libgit2

I've been using objecitive-git and libgit2 to try to implement pull functionality. As git pull is just a 'porcelain' command and is made up of a git fetch followed by a git merge origin/master then that would be how I implemented it.

The fetch is performed using the method in objective-git from the fetch branch on github.

[remote fetchWithCredentialProvider:nil error:&error progress:nil];

The code below is what is done after the fetch (which I know succeeds):

// Get the local branch
GTBranch *localBranch = [repo localBranchesWithError:nil][0];
// Get the remote branch
GTBranch *remoteBranch = [repo remoteBranchesWithError:nil][0];

// Get the local & remote commit
GTCommit *localCommit = [localBranch targetCommitAndReturnError:nil];
GTCommit *remoteCommit = [remoteBranch targetCommitAndReturnError:nil];

// Get the trees of both
GTTree *localTree = localCommit.tree;
GTTree *remoteTree = remoteCommit.tree;

// Get OIDs of both commits too
GTOID *localOID = localCommit.OID;
GTOID *remoteOID = remoteCommit.OID;

// Find a merge base to act as the ancestor between these two commits
GTCommit *ancestor = [repo mergeBaseBetweenFirstOID:localOID secondOID:remoteOID error:&error];
if (error) {
    NSLog(@"Error finding merge base: %@", error);
}
// Get the ancestors tree
GTTree *ancestorTree = ancestor.tree;

// Merge into the local tree
GTIndex *mergedIndex = [localTree merge:remoteTree ancestor:ancestorTree error:&error];
if (error) {
    NSLog(@"Error mergeing: %@", error);
}

// Write the merge to disk and store the new tree
GTTree *newTree = [mergedIndex writeTreeToRepository:repo error:&error];
if (error) {
    NSLog(@"Error writing merge index to disk: %@", error);
}

After the mergedIndex which starts out in memory has been written as a tree to disk (writeTreeToRepository uses git_index_write_tree_to) there is no change in the git repos status. I'm assuming I'm missing a last step to make the new tree HEAD or merge it with HEAD or something similar but I'm not sure exactly what.

Any help would be much obliged.


Source: (StackOverflow)

Creating Repository with Objective-Git

I am trying to create a Git repository using objective-git. The documentation is somewhat lacking on how the GT classes work together to create a repository so I'm kind of stuck.

This is what I have working so far:

GTRepository *newRepo = [GTRepository initializeEmptyRepositoryAtFileURL:repoURL error:&error]

I then copy a bunch of files into that directory. I can open then the repo in a Git client and see those files in the working directory. Everything looks good so far. But this is where I'm stuck, what is my next move to actually create a branch and commit those files?

EDIT: I have now gotten the GTIndex from my GTRepository (though, the fileURL property of the index is still nil, so I'm not sure how to generate that file). I iterate through my files, calling addFile:error: which creates GTIndexEntries in my index. I then call writeTree: and get back a GTTree that I pass into [repository createCommitWithTree:newTree message:@"Initial Commit" parents:nil updatingReferenceNamed:nil error:&error];. This returns a valid GTCommit object and no NSError, but I would expect that [repository headReferenceWithError:&error]; would now return a reference to the newly created commit, but it still returns nil. Is there a step I am missing to finalize this commit?


Source: (StackOverflow)

Swift with objective-git: Overloads for 'createCommitWithTree' exist with these partially matching parameter lists

I am using objective-git with Swift and cannot compile the GTRepository.createCommitWithTree method.

The method can optionally be called without author : GTSignature and committer : GTSignature parameters.

I'm new to Swift and overloading functions. I'd like to know how to structure this so it will compile.

My code uses all the types specified in the objective-git method:

func commitTree ( tree : GTTree ) {

    let message : NSString
    let author : GTSignature
    let committer : GTSignature
    let parents : NSArray
    let updatingReferenceNamed : NSString
    var error : NSError?

    GTRepository.createCommitWithTree( tree, message, author, committer, parents, updatingReferenceNamed, &error )
}

In this code, compiler cannot invoke method with an argument list of these types. Compiler provides additional information: "Overloads for 'createCommitWithTree' exist with these partially matching parameter lists: (GTTree, message: String, author: GTSignature, committer: GTSignature, parents: [AnyObject]?, updatingReferenceNamed: String?), (GTTree, message: String, parents: [AnyObject]?, updatingReferenceNamed: String?)"

If I refactor to use the types suggested above, compiler won't compile with "Ambiguous reference to member 'createCommitWithTree'"

How do I write this to compile?

Thanks


Source: (StackOverflow)

Objective-Git Merge

I am using Objective-Git. I cannot get the following method to work:

- (GTIndex *)merge:(GTTree *)otherTree ancestor:(GTTree *)ancestorTree error:(NSError **)error

No error is returned, but the index returned is empty, while it exists, all attributes are nil. The merge operation does not take place, I can't write out a tree as I cannot obtain the index resulting from the attempted merge.

Has anybody managed to successfully perform a merge using objective git - How? Help!

        GTBranch *branch1 = branches[0];
        GTCommit *commit1 = [branch1 targetCommitAndReturnError:NULL];
        GTOID *oid1 =  commit1.OID;
        GTTree *tree1 = commit1.tree;

        GTBranch *branch2 = branches[1];
        GTCommit *commit2 = [branch2 targetCommitAndReturnError:NULL];
        GTTree *tree2 = commit2.tree;
        GTOID *oid2 =  commit2.OID;

        GTRepository *repo = branch1.repository;

        NSError *error;
        GTCommit *ancestor = [repo mergeBaseBetweenFirstOID:oid1 secondOID:oid2 error:&error];
        if (error){
            NSLog(@"%@", error.description);
        }
        GTTree *ancTree = ancestor.tree;
        NSError *someError;
        NSLog(@"attempting merge into ""%@"" from ""%@"" with ancestor ""%@""", commit2.message, commit1.message,ancestor.message);
        GTIndex *mergedIndex = [tree2 merge:tree1 ancestor: ancTree error:&someError];  //returns index not backed by existing repo --> index_file_path = nil,  all attributes of git_index are nil
        if (someError){
            NSLog(@"%@", someError.description);
        }
        NSError *theError;
        GTTree *mergedtree = [mergedIndex writeTree:&theError]; //can't write out the tree as the index given back by merge: ancestor: error: does not reference a repo
        if (theError){
            NSLog(@"%@",theError);
        }
    }
}

Source: (StackOverflow)

XCode Build Failure - aclocal [/share] files missing

I'm trying to build an XCode project, and am getting the following error when trying to build:

...
Building for x86_64 i386 armv7 armv7s arm64
Building libssh2 for iphonesimulator7.1 x86_64
Please stand by...
/Users/jordanforeman/dev/ios/MyProject/objective-git/External/libssh2-ios/bin/iphonesimulator7.1-x86_64.sdk/build-libssh2.log
Command /bin/sh failed with exit code 1

** BUILD FAILED **


The following build commands failed:
    PhaseScriptExecution Run\ Script /Users/jordanforeman/Library/Developer/Xcode/DerivedData/MyProject-azifgvrunekkgmagzghrrvpdathe/Build/Intermediates/ObjectiveGitFramework.build/Debug-iphoneos/libssh2-iOS.build/Script-6A3C609117D5963700382DFF.sh
(1 failure)

Taking a look at build-libssh2.log I see the following:

aclocal: error: aclocal: file '/usr/local/share/aclocal/pkg.m4' does not exist
autoheader: error: AC_CONFIG_HEADERS not found in configure.ac
cp: src/libssh2_config.h.in: No such file or directory
configure.ac:5: error: possibly undefined macro: AM_CONFIG_HEADER
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.

...

tests/Makefile.am:11: error: SSHD does not appear in AM_CONDITIONAL
parallel-tests: installing './test-driver'
/usr/local/Cellar/automake/1.14.1/share/automake-1.14/am/check2.am: error: am__EXEEXT does not appear in AM_CONDITIONAL

full log here

Digging a little further, it would seem that all of the files in /usr/local/share/aclocal are symlinks to themselves. Is that intended, or is this causing my problems?

Also, when I run which aclocal I get pointed to /usr/local/bin/aclocal. Does this mean that XCode or some shell script is trying to use the wrong aclocal install? If so - how do I fix that?

That's about as far as I've got right now. I'm going to keep digging, and I'll update this as I learn more.


Source: (StackOverflow)