1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-05-17 22:32:58 +02:00

Merge branch 'master' into feature/better-file-opening

This commit is contained in:
Jesse Duffield 2018-08-08 07:41:55 +10:00
commit fb5d25c9e9
6 changed files with 260 additions and 99 deletions

44
.travis.yml Normal file
View File

@ -0,0 +1,44 @@
language: go
sudo: false
env:
- DEP_VERSION="0.5.0"
matrix:
include:
- go: 1.x
env: LATEST=true
- go: 1.7
- go: tip
allow_failures:
- go: tip
before_install:
# Download the binary to bin folder in $GOPATH
# - curl -L -s https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-386 -o $GOPATH/bin/dep
- curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
- ls
- ls */*
# Make the binary executable
- chmod +x $GOPATH/bin/dep
- ls $GOPATH/bin/
- dep ensure
- go get github.com/mitchellh/gox
install:
-
script:
# - go get -v ./...
# - diff -u <(echo -n) <(gofmt -d .) # can't make gofmt ignore vendor directory
# - go vet $(go list ./... | grep -v /vendor/)
- if [ "${LATEST}" = "true" ]; then gox -os="linux darwin windows" -arch="amd64" -output="lazygit.." -ldflags "-X main.Rev=`git rev-parse --short HEAD`" -verbose ./...; fi
- ls */*
deploy:
provider: releases
skip_cleanup: true
api_key:
secure: TnB8I+swjicHuGTXk3ncm1Aaa12eIJqWV/Lhcnbb01i39p6+fyn3vDMdWPcejt3R8gcJqv4wyP8UQVO9G1qkLppt6V/qAuY5x6nX0MgEa3t+8JLJnGYHZYsuIgan/ecAmeu5+6dgUhr9Oq6zQOEv/O88NsALzMlqnEQNXI8XSoScfhkiVDIp3zWov0vBizCdThnNgTx9zRpJVoqxmhWvgt+me2+fOhSx1Y+3ZA2gE7zq8IFAbxp36d0rsR5lKqmTuF+YsF9iQ7Ar+xCjbRunLsZx+VwGqGfpS/qS7EwsEqBI0vEO76eFJkwEsIzOvJiFNhBDUu3upquBFMT4uzxRxH3eV+J4mZtu29UDLdvKI5Q730Lk9AgmH4now+RmP08M0SEXJa+AnHeuBv2u1iU5bu+sI6CORVQzKQwOph9AABDjSZ54wrXIpYEeIW2sz8nx+hiG6QL1mqfM/l+55BR69u3vxKYMryQBxPuzhZCTOqqI4uahlb6GIUNZJ9vGZeIA9HFJq3ymW8cdrpYzhKf3Nx9jK+Yb81h5/AHq9iChXEC63VPCDXXGRllh2UYWNYCaAdtk+ekpLR8299e4CaEregy6g5U2S3/xrBKl87miu1uJ/fquXoxGdSU+JcmsmXZ26sGIU2TCYdNjSfIgpOyfMmB4JNtKHqWRHA9Fe42CRpA=
file:
- lazygit.windows.amd64.exe
- lazygit.darwin.amd64
- lazygit.linux.amd64
on:
repo: jesseduffield/lazygit
tags: true
condition: $LATEST = true

74
CODE-OF-CONDUCT.md Normal file
View File

@ -0,0 +1,74 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the [project leader](https://github.com/jesseduffield).
All complaints will be reviewed and investigated and will result in a response that
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org

34
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,34 @@
# Contributing
♥ We love pull requests from everyone !
When contributing to this repository, please first discuss the change you wish
to make via issue, email, or any other method with the owners of this repository
before making a change.
## So all code changes happen through Pull Requests
Pull requests are the best way to propose changes to the codebase. We actively
welcome your pull requests:
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests.
3. If you've added code that need documentation, update the documentation.
4. Be sure to test your modifications.
5. Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
6. Issue that pull request!
## Code of conduct
Please note by participating in this project, you agree to abide by the [code of conduct].
[code of conduct]: https://github.com/jesseduffield/lazygit/blob/master/CODE-OF-CONDUCT.md
## Any contributions you make will be under the MIT Software License
In short, when you submit code changes, your submissions are understood to be
under the same [MIT License](http://choosealicense.com/licenses/mit/) that
covers the project. Feel free to contact the maintainers if that's a concern.
## Report bugs using Github's [issues](https://github.com/jesseduffield/lazygit/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new
issue](https://github.com/jesseduffield/lazygit/issues/new); it's that easy!

View File

@ -21,7 +21,7 @@ Please note:
If you get an error claiming that lazygit cannot be found or is not defined, you may need to add `~/go/bin` to your $PATH (MacOS/Linux), or `%HOME%\go\bin` (Windows) If you get an error claiming that lazygit cannot be found or is not defined, you may need to add `~/go/bin` to your $PATH (MacOS/Linux), or `%HOME%\go\bin` (Windows)
### Ubuntu ### Ubuntu
Packages for Ubuntu 14.04 and up are available via Launchpad PPA. Packages for Ubuntu 16.04 and up are available via Launchpad PPA.
They are built daily, straight from master branch. They are built daily, straight from master branch.
@ -57,7 +57,7 @@ sudo apt-get install lazygit
- [ ] i18n - [ ] i18n
## Contributing ## Contributing
I'll find a good template for contributing and then add it to the repo (or if somebody has a suggestion please put up a PR) We love your input! Please check out the [contributing guide](CONTRIBUTING.md).
## Work in progress ## Work in progress
This is still a work in progress so there's still bugs to iron out and as this is my first project in Go the code could no doubt use an increase in quality, but I'll be improving on it whenever I find the time. If you have any feedback feel free to [raise an issue](https://github.com/jesseduffield/lazygit/issues)/[submit a PR](https://github.com/jesseduffield/lazygit/pulls). This is still a work in progress so there's still bugs to iron out and as this is my first project in Go the code could no doubt use an increase in quality, but I'll be improving on it whenever I find the time. If you have any feedback feel free to [raise an issue](https://github.com/jesseduffield/lazygit/issues)/[submit a PR](https://github.com/jesseduffield/lazygit/pulls).

View File

@ -113,7 +113,7 @@ func handleFileRemove(g *gocui.Gui, v *gocui.View) error {
func handleIgnoreFile(g *gocui.Gui, v *gocui.View) error { func handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
file, err := getSelectedFile(g) file, err := getSelectedFile(g)
if err != nil { if err != nil {
return err return createErrorPanel(g, err.Error())
} }
if file.Tracked { if file.Tracked {
return createErrorPanel(g, "Cannot ignore tracked files") return createErrorPanel(g, "Cannot ignore tracked files")

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"regexp"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -117,7 +118,7 @@ func platformShell() (string, string) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
return "cmd", "/c" return "cmd", "/c"
} }
return "sh", "-c" return "bash", "-c"
} }
func runDirectCommand(command string) (string, error) { func runDirectCommand(command string) (string, error) {
@ -165,72 +166,6 @@ func withPadding(str string, padding int) string {
return str + strings.Repeat(" ", padding-len(str)) return str + strings.Repeat(" ", padding-len(str))
} }
func branchFromLine(line string, index int) Branch {
recency, name := branchStringParts(line)
branchType, branchBase, colourAttr := branchPropertiesFromName(name)
if index == 0 {
recency = " *"
}
colour := color.New(colourAttr)
displayString := withPadding(recency, 4) + coloredString(name, colour)
return Branch{
Name: name,
Type: branchType,
BaseBranch: branchBase,
DisplayString: displayString,
}
}
func getGitBranches() []Branch {
branches := make([]Branch, 0)
// check if there are any branches
branchCheck, _ := runCommand("git branch")
if branchCheck == "" {
return append(branches, branchFromLine("master", 0))
}
if rawString, err := runDirectCommand(getBranchesCommand); err == nil {
branchLines := splitLines(rawString)
for i, line := range branchLines {
branches = append(branches, branchFromLine(line, i))
}
} else {
// TODO: DRY this up
branches = append(branches, branchFromLine(gitCurrentBranchName(), 0))
}
branches = getAndMergeFetchedBranches(branches)
return branches
}
func branchAlreadyStored(branchLine string, branches []Branch) bool {
for _, branch := range branches {
if branch.Name == branchLine {
return true
}
}
return false
}
// here branches contains all the branches that we've checked out, along with
// the recency. In this function we append the branches that are in our heads
// directory i.e. things we've fetched but haven't necessarily checked out.
// Worth mentioning this has nothing to do with the 'git merge' operation
func getAndMergeFetchedBranches(branches []Branch) []Branch {
rawString, err := runDirectCommand("git branch --sort=-committerdate --no-color")
if err != nil {
return branches
}
branchLines := splitLines(rawString)
for _, line := range branchLines {
line = strings.Replace(line, "* ", "", -1)
line = strings.TrimSpace(line)
if branchAlreadyStored(line, branches) {
continue
}
branches = append(branches, branchFromLine(line, len(branches)))
}
return branches
}
// TODO: DRY up this function and getGitBranches // TODO: DRY up this function and getGitBranches
func getGitStashEntries() []StashEntry { func getGitStashEntries() []StashEntry {
stashEntries := make([]StashEntry, 0) stashEntries := make([]StashEntry, 0)
@ -589,33 +524,107 @@ func gitCurrentBranchName() string {
return strings.TrimSpace(branchName) return strings.TrimSpace(branchName)
} }
const getBranchesCommand = `set -e // A line will have the form '10 days ago master' so we need to strip out the
git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD | { // useful information from that into timeNumber, timeUnit, and branchName
seen=":" func branchInfoFromLine(line string) (string, string, string) {
git_dir="$(git rev-parse --git-dir)" r := regexp.MustCompile("\\|.*\\s")
while read line; do line = r.ReplaceAllString(line, " ")
date="${line%%|*}" words := strings.Split(line, " ")
branch="${line##* }" return words[0], words[1], words[3]
if ! [[ $seen == *:"${branch}":* ]]; then }
seen="${seen}${branch}:"
if [ -f "${git_dir}/refs/heads/${branch}" ]; then func abbreviatedTimeUnit(timeUnit string) string {
printf "%s\t%s\n" "$date" "$branch" r := regexp.MustCompile("s$")
fi timeUnit = r.ReplaceAllString(timeUnit, "")
fi timeUnitMap := map[string]string{
done \ "hour": "h",
| sed 's/ months /m /g' \ "minute": "m",
| sed 's/ month /m /g' \ "second": "s",
| sed 's/ days /d /g' \ "week": "w",
| sed 's/ day /d /g' \ "year": "y",
| sed 's/ weeks /w /g' \ "day": "d",
| sed 's/ week /w /g' \ "month": "m",
| sed 's/ hours /h /g' \ }
| sed 's/ hour /h /g' \ return timeUnitMap[timeUnit]
| sed 's/ minutes /m /g' \ }
| sed 's/ minute /m /g' \
| sed 's/ seconds /s /g' \ func getBranches() []Branch {
| sed 's/ second /s /g' \ branches := make([]Branch, 0)
| sed 's/ago//g' \ rawString, err := runDirectCommand("git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD")
| tr -d ' ' if err != nil {
return branches
}
branchLines := splitLines(rawString)
for i, line := range branchLines {
timeNumber, timeUnit, branchName := branchInfoFromLine(line)
timeUnit = abbreviatedTimeUnit(timeUnit)
if branchAlreadyStored(branchName, branches) {
continue
}
branch := constructBranch(timeNumber+timeUnit, branchName, i)
branches = append(branches, branch)
}
return branches
}
func constructBranch(prefix, name string, index int) Branch {
branchType, branchBase, colourAttr := branchPropertiesFromName(name)
if index == 0 {
prefix = " *"
}
colour := color.New(colourAttr)
displayString := withPadding(prefix, 4) + coloredString(name, colour)
return Branch{
Name: name,
Type: branchType,
BaseBranch: branchBase,
DisplayString: displayString,
}
}
func getGitBranches() []Branch {
// check if there are any branches
branchCheck, _ := runCommand("git branch")
if branchCheck == "" {
return []Branch{constructBranch("", gitCurrentBranchName(), 0)}
}
branches := getBranches()
if len(branches) == 0 {
branches = append(branches, constructBranch("", gitCurrentBranchName(), 0))
}
branches = getAndMergeFetchedBranches(branches)
return branches
}
func branchAlreadyStored(branchName string, branches []Branch) bool {
for _, existingBranch := range branches {
if existingBranch.Name == branchName {
return true
}
}
return false
}
// here branches contains all the branches that we've checked out, along with
// the recency. In this function we append the branches that are in our heads
// directory i.e. things we've fetched but haven't necessarily checked out.
// Worth mentioning this has nothing to do with the 'git merge' operation
func getAndMergeFetchedBranches(branches []Branch) []Branch {
rawString, err := runDirectCommand("git branch --sort=-committerdate --no-color")
if err != nil {
return branches
}
branchLines := splitLines(rawString)
for _, line := range branchLines {
line = strings.Replace(line, "* ", "", -1)
line = strings.TrimSpace(line)
if branchAlreadyStored(line, branches) {
continue
}
branches = append(branches, constructBranch("", line, len(branches)))
}
return branches
} }
`