PoshCode / PSGit

A PowerShell implementation of Git, mapping git commands to Verb-Noun and objects.
105 stars 15 forks source link

Get-Change #10

Closed Jaykul closed 9 years ago

Jaykul commented 9 years ago

This is basically the file changes portion of git status

Jaykul commented 9 years ago

So, I'm really looking for some design thoughts from people about this...

git status returns FOUR things:

  1. Repository Info (branch name, and whether you're up to date with the origin)
  2. A list of staged files, with their state
  3. A list of non-staged files, with their state
  4. instructions for how to get files from one state to the other:
    1. for staged files:
      1. how to unstage them.
    2. for unstaged files:
      1. how to stage them
      2. how to revert them

In PowerShell, it's an anti-pattern to output that many different types of objects, so the only reasonable way to do something like that would be to return a single object with all of those things as properties (e.g.: Info, StagedChanges , UnstagedChanges and then apply some creative custom formatting (not just format-table with grouping, but custom formatting with the instructions hardcoded in the format file). This sounds terrible, and would result in the output being non-pipeable ...

The simple alternative is to have two commands: Get-GitInfo and Get-GitStatus, with Get-GitInfo returning the repository information (including the branch and whether you're up to date), and the Status command returning just a list of "changes" which is a file name and a property for:

  1. Staged = True, False
  2. Change = New, Modified, Removed, Renamed (and any combination thereof)

Additionally, Get-GitStatus would sort the output by Staged and then by Change, and would have Verbose output (before the staged changes, and before the unstaged changes) which would include the instructions.

Then, if you want a full replacement for git status you just write yourself:

function gitstatus { 
    Get-GitInfo | Out-Default
    Get-GitStatus -Verbose | Out-Default
}

What do you think?

KirkMunro commented 9 years ago

Being able to see the Git status as output from a single command is convenient. It's also text-based reporting. Natively PowerShell doesn't support multiple types/tables, as you said, but FormatPx enables this support, and it is very, very handy for reporting purposes. I think there should be individual commands for individual bits of Git status that you may want to do something with, plus one command that does what you suggested, shows well-formatted Git status output in a report. How about Show-GitStatus, and have the module take a dependency on FormatPx? Show is a great verb for reporting or popping up a UI, and I wouldn't apply the anti-pattern argument to a Show-* command that is used for reporting purposes. Plus, if you were using FormatPx you could still pipe to other things if you wanted to since objects would be returned rather than format data.

omidkrad commented 9 years ago

This is great. My suggestion is, if possible at all, define a global parameter across all PSGit cmdlets to output the equivalent git command for what is being executed. For example -AsNativeGit. If that is not possible, then please include equivalent git commands in help of each cmdlet and their parameters. This paring will be useful for learning/comparison as well as communicating commands to people who are on other platforms.

Jaykul commented 9 years ago

I think it makes a lot of sense to document an example in the help, but I'm not taking on extra code or code paths for the sake of helping people learn native git.exe -- frankly, there's no way that these cmdlets would be a productive way to learn the native git syntax :wink:

jrich523 commented 9 years ago

I think there should be a Show-GitStatus which gives a similar output to Git Status and then a Get-GitStatus and Get-GitInfo

im torn on having a Show-GitStatus and Get-GitStatus, but I guess thats ok..

That should cover all cases and still make it powershell friendly..

Having the verbose output for the learning would be good, also easy to turn off, maybe even have its own global var to enable/disable..

I dont really care too much for the map back to git.exe, I think anyone who knows Git will learn the cmdlets quickly, and anyone who doesnt, wont have as much pain learning it this way..

JayBazuzi commented 9 years ago

Git's current UX is horrible. Just a mess. Don't feel like you have to stick to it. Write PowerShell-idiomatic cmdlets that do Git stuff.

For git status, write:

And then Get-GitStatus would combine these results in to one object that formats in a way similar to git status, just for convenience.

Jaykul commented 9 years ago

How about three commands (the "Git" prefix is in the psd1):

I like the idea of using Show for the "for display only" wrappers, and using Changes as the noun resolves the dilemma of similar names (and has the benefit of being correct and more descriptive).

KirkMunro commented 9 years ago

You mean "Change" for the noun, and not "Changes", right?

-----Original Message----- From: "Joel Bennett" notifications@github.com Sent: ‎2015-‎05-‎09 7:43 PM To: "PoshCode/PSGit" PSGit@noreply.github.com Cc: "Kirk Munro" poshoholic@gmail.com Subject: Re: [PSGit] Get-Status (#10)

How about three commands (the "Git" prefix is in the psd1): Get-Changes with three parameter sets (default shows all, and -Staged and -Unstaged to filter). Get-CurrentBranch I don't quite like this name, but it's less generic than Get-Info and I'm not sure about having a separate command to fetch the remote status (I'm not sure there's any point in the command if it's just the name of the current branch, but if there is, we could add a -Name or -NameOnly switch) Show-Status as a wrapper for display. I like the idea of using Show for the "for display only" wrappers, and using "Changes" as the noun resolves the dilemma of similar names (and has the benefit of being correct and more descriptive). — Reply to this email directly or view it on GitHub.

Jaykul commented 9 years ago

Ugh. Get-GitChange ... now I want to make it Status again :-P

jrich523 commented 9 years ago

Get-GitFileStatus, alias of GFS

dahlbyk commented 9 years ago

Having the verbose output for the learning would be good, also easy to turn off, maybe even have its own global var to enable/disable..

I don't recall off-hand, but I'm certain there is a Git config setting for this that could be respected.


I like Get-GitFileStatus with filters for -Staged and -Unstaged (or -WorkDir aligns more closely with Git terminology).

Instead of Get-CurrentBranch perhaps Get-GitHeadStatus?

On the Show-GitStatus front, what's the mechanism that shows parent info above a Get-ChildItem? It seems like that might be a suitable way to render the HEAD status before the file status.

Jaykul commented 9 years ago

WhachuOnAbout @dahlbyk, WorkDir? git status shows:

Changes to be committed:
...
Changes not staged for commit:
...

I'm pretty sure, we need to choose either index or stage and consistently use exactly ONE word for this thing (unlike git).

Jaykul commented 9 years ago

The mechanism that GCI uses to display the parent info is just GROUPing. You can do that with anything using Format-Table -Group [something] ... but you have to actually have the information to group on.

dahlbyk commented 9 years ago

WhachuOnAbout @dahlbyk, WorkDir?

Er, that's how we refer to it in LG2S. -Unstaged sounds great. :sheep:

The mechanism that GCI uses to display the parent info is just GROUPing. You can do that with anything using Format-Table -Group [something] ... but you have to actually have the information to group on.

Was not aware of -Group - nifty. Would it make sense to attach an instance representing repo (branch) status to each change entry with the sole purpose of grouping by it? This would let you iterate over several repositories with a single call and get reasonable status output for all.

Jaykul commented 9 years ago

Yes, it would make sense to attach the repo/branch status to every change entry for the purpose of making get-status output actual objects and still be pretty.

P.S. Normally, the WorkDir is just the folder that your .git is in, right? I mean, I know there's a git-new-workdir that lets you make a new workdir for a specific branch, so you can have more than one branch editable at a time ... I'm not sure how that works with our bits, we should probably test it, or just say it's not supported to separate your repo and workdir ;-)

dahlbyk commented 9 years ago

Normally, the WorkDir is just the folder that your .git is in, right? I mean, I know there's a git-new-workdir that lets you make a new workdir for a specific branch, so you can have more than one branch editable at a time ... I'm not sure how that works with our bits, we should probably test it, or just say it's not supported to separate your repo and workdir ;-)

Yeah, for non-bare repositories the working directory is the parent of .git. Bare repositories don't have an index or working directory. Specifying both is supported by LibGit2Sharp.RepositoryOptions.

jrich523 commented 9 years ago

We should probably ignore the working directory stuff, it could make a mess. in windows it uses a link to the .git (didnt test, just read) so that if you do an rm, you'll end up blowing away your actual git repo.

also, im not sure i've ever talked to anyone thats done it :)

part of the goal is to make this as easy as possible for folks (admins, since we've got a lot of them in PS) so i think its best we ignore edge cases