Git Product home page Git Product logo

Comments (8)

ghedo avatar ghedo commented on May 24, 2024

Alternatively we could always return a hash, and make the path parameter optional so that if it's passed the returned hash has only one element.

from p5-git-raw.

jacquesg avatar jacquesg commented on May 24, 2024

Ok, but we'll need to add an extra parameter to status, which takes a git_status_options and use this to invoke git_status_foreach_ext. If a path parameter is specified, we could add it to git_status_options.pathspec and add GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH to the flags.

What may even be slightly nicer is to actually use@_ after the options parameter as a list of files ex.

sub status
{
    my ($self, $opts, @files) = @_;
}

http://libgit2.github.com/libgit2/#HEAD/type/git_status_options

from p5-git-raw.

ghedo avatar ghedo commented on May 24, 2024

Why would status() need to take a git_status_options? It can just create the struct internally. Also, I don't think the user needs to be able to set the flags since the default looks pretty sane to me. As for the pathspec thing, yes, that's what I was thinking about. Also, using git_status_list_new looks easier than git_status_foreach_ext.

from p5-git-raw.

jacquesg avatar jacquesg commented on May 24, 2024

I didn't even know about git_status_list_new :) Have been using git_status_foreach_ext for quite some time, pre 0.19.

The defaults don't always make sense:

#define GIT_STATUS_OPT_DEFAULTS \
        (GIT_STATUS_OPT_INCLUDE_IGNORED | \
        GIT_STATUS_OPT_INCLUDE_UNTRACKED | \
        GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS)

For one, GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS is not what git does when you run git status. It only shows you the ignored directory. The defaults also don't quite cater for all the different "rename" possibilities.

from p5-git-raw.

ghedo avatar ghedo commented on May 24, 2024

Does libgit2 even list untracked directories (vs. only listing files)? In any case, the worst that can happen is that the user gets more information than he needs. As for the renames, they aren't even supported by Git::Raw right now, but I guess the GIT_STATUS_OPT_*_TO_* could be included as well... my point was that the user shouldn't even need to set custom flags (and it would be pretty ugly to expose them to Perl... which is why status() returns an array of strings instead of just an int).

from p5-git-raw.

jacquesg avatar jacquesg commented on May 24, 2024

Ok, agreed. Here is some code I hacked together (its only a proof of concept) a while ago to get the info. One of the methods gets files in the index that are conflicted, which could be adapted and added to Git::Raw::Index (and probably methods to resolve/clear it).

Actually I did use git_status_list_new :)

HV *
status_index_files(self)
    Repository self

    CODE:
    {
        size_t i;
        git_status_list *status;
        HV *files;

        git_status_options opt = GIT_STATUS_OPTIONS_INIT;
        opt.show = GIT_STATUS_SHOW_INDEX_ONLY;
        opt.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES | GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;

        git_check_error (git_status_list_new (&status, self, &opt));

        files = newHV();
        for (i = 0; i < git_status_list_entrycount (status); ++i)
        {
            SV **indexFiles;
            const char *old_path, *new_path;
            const char *key = NULL;
            const git_status_entry *s = git_status_byindex (status, i);

            if (s->status == GIT_STATUS_CURRENT || s->status == GIT_STATUS_INDEX_TYPECHANGE)
            {
                continue;
            }

            new_path = s->head_to_index->new_file.path;
            old_path = s->head_to_index->old_file.path;

            if (s->status & GIT_STATUS_INDEX_NEW)
            {
                key = "new";
            }
            else if (s->status & GIT_STATUS_INDEX_MODIFIED)
            {
                key = "modified";
            }
            else if (s->status & GIT_STATUS_INDEX_DELETED)
            {
                key = "deleted";
            }
            else if (s->status & GIT_STATUS_INDEX_RENAMED)
            {
                key = "renamed";
            }

            indexFiles = hv_fetch (files, key, strlen (key), 1);
            if (indexFiles != NULL)
            {
                HV * fileInfo = newHV();

                if (!SvOK (*indexFiles))
                {
                    *indexFiles = newRV_noinc ((SV*) newAV());
                }

                hv_store (fileInfo, "old", strlen ("old"), newSVpv (old_path, 0), 0);
                hv_store (fileInfo, "new", strlen ("new"), newSVpv (new_path, 0), 0);

                av_push ((AV *) SvRV (*indexFiles), (SV *) newRV_noinc ((SV*) fileInfo));
            }
        }

        sv_2mortal ((SV*) files);
        RETVAL = files;
    }

    OUTPUT: RETVAL

HV *
status_worktree_files(self)
    Repository self

    CODE:
    {
        size_t i;
        git_status_list *status;
        HV *files;

        git_status_options opt = GIT_STATUS_OPTIONS_INIT;
        opt.show = GIT_STATUS_SHOW_WORKDIR_ONLY;
        opt.flags = GIT_STATUS_OPT_EXCLUDE_SUBMODULES | GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;

        git_check_error (git_status_list_new (&status, self, &opt));

        files = newHV();
        for (i = 0; i < git_status_list_entrycount (status); ++i)
        {
            SV ** worktreeFiles;
            const char *old_path, *new_path;
            const char *key = NULL;
            const git_status_entry *s = git_status_byindex (status, i);

            if (s->status == GIT_STATUS_CURRENT || s->status == GIT_STATUS_WT_TYPECHANGE)
            {
                continue;
            }

            new_path = s->index_to_workdir->new_file.path;
            old_path = s->index_to_workdir->old_file.path;

            if (s->status & GIT_STATUS_WT_NEW)
            {
                key = "new";
            }
            else if (s->status & GIT_STATUS_WT_MODIFIED)
            {
                key = "modified";
            }
            else if (s->status & GIT_STATUS_WT_DELETED)
            {
                key = "deleted";
            }
            else if (s->status & GIT_STATUS_WT_RENAMED)
            {
                key = "renamed";
            }

            worktreeFiles = hv_fetch (files, key, strlen (key), 1);
            if (worktreeFiles != NULL)
            {
                HV * fileInfo = newHV();

                if (!SvOK (*worktreeFiles))
                {
                    *worktreeFiles = newRV_noinc ((SV*) newAV());
                }

                hv_store (fileInfo, "old", strlen ("old"), newSVpv (old_path, 0), 0);
                hv_store (fileInfo, "new", strlen ("new"), newSVpv (new_path, 0), 0);

                av_push ((AV *) SvRV (*worktreeFiles), (SV *) newRV_noinc ((SV*) fileInfo));
            }
        }

        sv_2mortal ((SV*) files);
        RETVAL = files;
    }

    OUTPUT: RETVAL

AV *
status_unmerged_files(self)
    Repository self

    CODE:
    {
        int rc = 0;
        size_t count = 0, i = 0;
        Index index;

        rc = git_repository_index (&index, self);
        git_check_error (rc);

        rc = git_index_read (index, 0);
        if (rc == GIT_OK)
        {
            HV *files = newHV();
            AV *result = newAV();
            I32 iter = 0;
            HE *hashEntry = NULL;

            if (git_index_has_conflicts (index))
            {
                size_t i = 0, count = git_index_entrycount (index);
                for (i = 0; i < count; ++i)
                {
                    const git_index_entry *entry = git_index_get_byindex (index, i);
                    if (git_index_entry_stage (entry) != 0)
                    {
                        hv_store (files, entry->path, strlen (entry->path), newSViv (1), 0);
                    }
                }
            }

            iter = hv_iterinit (files);
            while ((hashEntry = hv_iternext (files)) != NULL)
            {
                av_push (result, newSVpv (HeKEY (hashEntry), HeKLEN (hashEntry)));
            }

            hv_clear (files);
            hv_undef (files);

            RETVAL = result;
        }

        git_index_free (index);
    }

    OUTPUT: RETVAL

from p5-git-raw.

ghedo avatar ghedo commented on May 24, 2024

I haven't run your code but it doesn't look like it does what I had in mind. I have pushed 34b5a96 (see status branch) which implements status() like pygit2 does:

my $status = $repo -> status -> {'some_file'} # ['worktree_new']
my $status = $repo -> status('some_file') -> {'some_file'} # ['worktree_new']
...

It doesn't yet support renames though.

from p5-git-raw.

ghedo avatar ghedo commented on May 24, 2024

Actually, it's 9c0d719 not 34b5a96

from p5-git-raw.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.