Scoop
Scoop copied to clipboard
[Feature] Use LibGit2Sharp instead of installing whole Git
Feature Request
Is your feature request related to a problem? Please describe.
Scoop looses a bit of it's magic if you don't install git (buckets, updates, etc..)
Describe the solution you'd like
Why not use LibGit2Sharp? It lets you clone repositories with PowerShell while it's only a few hundred kilobytes. I'm not sure about if it can pull / show new commits but I doubt it'd need to be that bigger. Because of it's small size it could come with the scoop installer and let people easily add other buckets
Describe alternatives you've considered
None other I can think of
It's a nice idea, but can the library show git logs and style them like we do currently?
Marked and MAY adopt this idea, thanks!
Removing the dependency of 7zip would be nice too, but https://github.com/thoemmi/7Zip4Powershell uses 7z.dll, and I recall that 7z.dll doesn't have all the functionality we need of 7zip.exe. I think it was that expanding .exe's required 7z.exe, but I'm not sure.
Well, I actually tried that before π https://github.com/ScoopInstaller/GitCloner/blob/master/src/gitcloner.ps1
It seems to support git log.
https://github.com/libgit2/libgit2sharp/wiki/git-log
https://github.com/libgit2/libgit2sharp/wiki/git-log-name-status
Well, I actually tried that before π https://github.com/ScoopInstaller/GitCloner/blob/master/src/gitcloner.ps1
It seems to support
git log. https://github.com/libgit2/libgit2sharp/wiki/git-log https://github.com/libgit2/libgit2sharp/wiki/git-log-name-status
Did you encounter any issues that stopped you from implementing git-cloner to scoop?
Probably the log issue. Don't know anymore π
Currently trying to implement the logging. (Failing to get the x minutes/hours ago part with the correct values)
Currently trying to implement the logging
I'll keep an eye on ScoopInstaller/GitCloner thank you ππ
So this is what I came up with. But there might be a license problem, because I based the ConvertTo-RelativeDate-Function on the show_date_relative() from Git itself. (I don't know if the GPL-2.0 allows us to do that. ð€·ðΒΒΒ½Γ’ΒΒΓ’ΒΒΓ―ΒΈΒ)
The output is the same as git --no-pager log --no-decorate --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' '$previousCommit..HEAD'.
Some commits get switched if they are commited at the exact same second. (not a problem)
<#
.SYNOPSIS
Shows the git log from a past commit hash to HEAD
.DESCRIPTION
A small script shows the git log from a given commit hash to the current HEAD
.PARAMETER Repository
Valid path to local Git repository
.PARAMETER StartHash
The commit hash uses to create the log '$hash..HEAD'
.PARAMETER Color
Switch for colored output
.EXAMPLE
PS > .\gitlogger.ps1 -Repository '~/scoop/bucket/main' -StartHash "2d09f7c00" -Color
#>
param (
[Parameter(Mandatory = $true, Position = 0)]
[ValidateScript( {
if (!(Test-Path $_ -Type Container)) {
throw "$_ is not a directory!"
} else {
$true
}
})]
[String] $Repository,
[Parameter(Mandatory = $true, Position = 1)]
[String] $StartHash = "",
[Switch] $Color
)
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class Kernel32
{
[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
}
"@
if([System.IntPtr]::Size -eq 8) {
[Kernel32]::LoadLibrary((Get-ChildItem "$PSScriptRoot\lib\win32\x64\git2-???????.dll" | Select-Object -First 1).FullName) | Out-Null
} else {
[Kernel32]::LoadLibrary((Get-ChildItem "$PSScriptRoot\lib\win32\x86\git2-???????.dll" | Select-Object -First 1).FullName) | Out-Null
}
Add-Type -Path "$PSScriptRoot\LibGit2Sharp.dll"
function ConvertTo-PluralizedString {
[OutputType([String])]
param (
[Parameter(Mandatory = $true)]
[Int]
$Value,
[Parameter(Mandatory = $true)]
[String]
$Singular,
[Parameter(Mandatory = $true)]
[String]
$Plural
)
if($Value -gt 1) {
return $Plural -f $Value
}
return $Singular -f $Value
}
# Based on https://github.com/git/git/blob/master/date.c
function ConvertTo-RelativeDate {
[OutputType([String])]
param (
[Parameter(Mandatory = $true, Position = 1)]
[DateTimeOffset]
$Date
)
$ts = New-TimeSpan -Start $Date.LocalDateTime.Ticks
$diff = $ts.TotalSeconds
if($diff -lt 0) {
return "in the future"
}
# Turn it into minutes
$diff = ($diff + 30) / 60;
if($diff -lt 90) {
return ConvertTo-PluralizedString -Singular "{0} minute ago" -Plural "{0} minutes ago" -Value ([int][Math]::Floor($diff))
}
# Turn it into hours
$diff = ($diff + 30) / 60;
if ($diff -lt 36) {
return ConvertTo-PluralizedString -Singular "{0} hour ago" -Plural "{0} hours ago" -Value ([int][Math]::Floor($diff))
}
# We deal with number of days from here on
$diff = ($diff + 12) / 24;
if ($diff -lt 14) {
return ConvertTo-PluralizedString -Singular "{0} day ago" -Plural "{0} days ago" -Value ([int][Math]::Floor($diff))
}
# Say weeks for the past 10 weeks or so
if ($diff -lt 70) {
return ConvertTo-PluralizedString -Singular "{0} week ago" -Plural "{0} weeks ago" -Value ([int][Math]::Floor(($diff + 3) / 7))
}
# Say months for the past 12 months or so
if ($diff -lt 365) {
return ConvertTo-PluralizedString -Singular "{0} month ago" -Plural "{0} months ago" -Value ([int][Math]::Floor(($diff + 15) / 30))
}
# Give years and months for 5 years or so
if ($diff -lt 1825) {
$totalmonths = ([int][Math]::Floor($diff) * 12 * 2 + 365) / (365 * 2);
$years = [int][Math]::Floor($totalmonths / 12);
$months = [int][Math]::Floor($totalmonths % 12);
if ($months) {
$sb = ConvertTo-PluralizedString -Singular "{0} year" -Plural "{0} years" -Value $years
# TRANSLATORS: "%s" is "<n> years"
return ConvertTo-PluralizedString -Singular "$sb, {0} month ago" -Plural "$sb, {0} months ago" -Value $months
} else {
return ConvertTo-PluralizedString -Singular "{0} year ago" -Plural "{0} years ago" -Value $years
}
}
# Otherwise, just years. Centuries is probably overkill.
return ConvertTo-PluralizedString -Singular "{0} year ago" -Plural "{0} years ago" -Value ([int][Math]::Floor(($diff + 183) / 365))
}
$repo = New-Object -TypeName LibGit2Sharp.Repository -ArgumentList $Repository
$properties = @{
IncludeReachableFrom = 'HEAD';
}
if($StartHash.Length -gt 0) {
$properties.ExcludeReachableFrom = $StartHash
}
$filter = New-Object -TypeName LibGit2Sharp.CommitFilter -Property $properties
# Recreates the following 'git log' command
# git --no-pager log --no-decorate --format='tformat: * %C(yellow)%h%Creset %<|(72,trunc)%s %C(cyan)%cr%Creset' '$previousCommit..HEAD'
try {
if(!$Color) {
$repo.Commits.QueryBy($filter) | ForEach-Object {
$msg = $_.MessageShort.Trim().PadRight(59)
if($msg.Length -gt 59) {
$msg = "{0}.." -f $msg.Substring(0, 57)
}
$row = " * {0} {1} {2}" -f $_.Sha.Substring(0, 9), $msg, (ConvertTo-RelativeDate -Date $_.Author.When)
Write-Output $row
}
} else {
$repo.Commits.QueryBy($filter) | ForEach-Object {
$msg = $_.MessageShort.Trim().PadRight(59)
if($msg.Length -gt 59) {
$msg = "{0}.." -f $msg.Substring(0, 57)
}
Write-Host -NoNewline " * "
Write-Host -NoNewline -ForegroundColor DarkYellow $_.Sha.Substring(0, 9)
Write-Host -NoNewline " $msg "
Write-Host -ForegroundColor DarkCyan (ConvertTo-RelativeDate -Date $_.Author.When)
}
}
} catch [Exception] {
Write-Output $_.Exception.Message
}
Using LibGit2Sharp would greatly accelerate installation speed, unzipping the main bucket is soo long..
I like the overall idea. Just a word of warning: LibGit2Sharp has been lacking a maintainer for a couple of years. That doesn't need to be a blocker, but you should weigh it into the overall effort of implementing this issue, since you may have to maintain your own fork.
Would be also cool if we used a DLL for 7-Zip (7z.dll) (if possible), since there's already DLLs in Scoop
Will be, maybe in a 'plugins' feature.
Another possible solution: Reducing MinGit to just git.exe , git-remote-https.exe, *.dll, license, ca-certs, and hook templates.
Results in a ~8 MB ZIP or ~16 MB on disk.

yeah i dont think mingw is needed
though having this means as git in PATH could conflict with a real git..?
What you see above is without mingw, but the DLLs are required to run git.exe. I just copied the DLLs over bit by bit until git.exe started working (in Windows Sandbox) :smile:
This version of git would only be used internally without exposing it to the user environment.
great! that should help cut down the installation setup time ππ (i mean git isn't installed right at setup but still is a core part of scoop)
great! that should help cut down the installation setup time ππ
That should be fixed now btw, because of https://github.com/ScoopInstaller/Install/pull/42
git for scoop is around 350MB (mingw64 being 150MB of it). Has there been any outcome out of this libgit2 effort lately?
copying over from duplicate discussion.
- i created this discussion as i was not actively aware of any small implementations of git for windows,
- but here there are many.
- so, switching to fossil would be more of a hack if there are not much additional benefits to it.
- but i don't know, as i have never used that; and never dived beneath the surface of git either.
continuing from here: https://github.com/ScoopInstaller/Scoop/discussions/5885
so, on the client's win 7 system, using extras/doublecmd application, i navigated to the scoop-apps directory, and the git-portable or whatever was at the top consuming whopping 3xx MB of space.
this is whopping due to following reasons:
- as that system is old and constrained on disk space.
- for non-tech people who do not use git, this is way too much of a consumption by a needless superfluous application
so, i'd like to explore using main/fossil vcs for pulling the git buckets. it was only 30-40 MB the last time i used that.
and it says that it can work with git. but i don't know if it can work with remote-gits too...
upside:
- uses
sqlitedbto store git info, so, the database might very well be used directly lol
downside:
- would still need to extract/use only
dlls etc, - since fossil has lots of other stuff (like issue tracker, wiki, browser GUI, etc) beside just the "git-like" part.
versions
$ scoop --version | head -n2
Current Scoop version:
v0.3.1 - Released at 2022-11-15
$ scoop info fossil
Name : fossil
Description : A simple, high-reliability, distributed software configuration management system.
Version : 2.23
Bucket : main
Website : https://www.fossil-scm.org
License : BSD-2-Clause
Updated at : 2023-11-02 01:54:26
Updated by : github-actions[bot]
Binaries : fossil.exe