Giter VIP home page Giter VIP logo

git-substatus's People

Contributors

beucismis avatar strboul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

git-substatus's Issues

not working

tried on two different directories with git repos:

Traceback (most recent call last):
  File "/home/eg/.local/bin/git-substatus", line 8, in <module>
    sys.exit(main())
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/__main__.py", line 11, in main
    GitSubstatusApplication(args).exec()
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/gitsubstatus.py", line 59, in exec
    statuses = status.get_status()
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 149, in get_status
    git_status = tuple(self.__get_statuses())
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 154, in __get_statuses
    status = self.__get_git_status(repo)
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 161, in __get_git_status
    if self.__is_status_clean():
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 181, in __is_status_clean
    btw_brackets = self.status_details[0].split("[")
IndexError: list index out of range
Traceback (most recent call last):
  File "/home/eg/.local/bin/git-substatus", line 8, in <module>
    sys.exit(main())
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/__main__.py", line 11, in main
    GitSubstatusApplication(args).exec()
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/gitsubstatus.py", line 59, in exec
    statuses = status.get_status()
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 149, in get_status
    git_status = tuple(self.__get_statuses())
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 154, in __get_statuses
    status = self.__get_git_status(repo)
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 164, in __get_git_status
    self.status_changes = StatusChanges.get_status_changes(self.status_details)
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 42, in get_status_changes
    cls.mapped_status_count = cls.__get_mapped_status_count()
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 105, in __get_mapped_status_count
    return dict(status_count_gen())
  File "/home/eg/.local/lib/python3.9/site-packages/git_substatus/status.py", line 100, in status_count_gen
    raise KeyError(f"Unknown status mapping: \"{k}\"")
KeyError: 'Unknown status mapping: "?"'

also I couldn't get the package from pip via pip install git-substatus

Add an option to look deeper in the directories

Add a command-line option (e.g. -L, --level) to choose how deep git-substatus should look at the dirs.

The current default is 1 (and can't be changed with an option), and it could be better if it was 2.

SyntaxWarning: "is" with a literal. Did you mean "=="?

Hi, This is a new warning added in Python 3.8 (release notes). There’s a subtle difference between the Python identity operator (is) and the equality operator (==). The "==" operator compares the value or equality of two objects, whereas the Python "is" operator checks whether two variables point to the same object in memory.

screenshot

We can filter the warning (library/warnings) or replace the "is" statement with "==".

Add interactive flag

To be used with certain flags (like, --fetch, --pull etc.)

git substatus --fetch --interactive
# Fetching `repo/`
# [Y]es, [N]o, [Q]uit

Control when color codes are sent to stdout

When running git-substatus with watch, the output is not clean due to the escape codes:

watch git-substatus
# Every 2.0s: git-substatus
# ^[90m directory: </home/myazici>^[0m
# • ^[1m^[34mdotfiles^[0m        ^[4m^[37mv0.4.4^[0m    ^[3m^[32m<sync>^[0m              ^[36m^[0m   ^[35m^[0m
# • ^[1m^[34mtmp-workbench^[0m   ^[4m^[37mupdates^[0m   ^[33m2 untracked & ahead 1^[0m   ^[36m^[0m   ^[35m^[0m

With watch git status the color is not there; but, when printed onto the screen, it is.

watch --color git-substatus shows the output with color, but that's a separate parameter added to the watch command.
If I add watch git -c color.status=always status, I see the git status with the escape code.


So how does git know when to add the escape codes?
Answer: there's a way to check if a file is opened on terminal

man test
...
-t FD file descriptor FD is opened on a terminal
...

echo '''
#!/bin/bash
text="Hello world"
if [ -t 1 ]; then
  echo "***stdout is a terminal***"
  text="$(printf "%s" "\e[31m$text\e[0m")"
fi
echo -e "$text"
''' > test.sh
chmod +x test.sh

./test.sh
# ***stdout is a terminal***
# Hello world
#

watch ./test.sh
# Every 2.0s: ./test.sh
# 
# Hello world
#

TODO

  • Implement that color codes are added if the stdout is going to the terminal
  • new arg: --color always prints color
  • new arg: --no-color never prints color

  • Add tests with watch

Watch 1 time & parse the output.

watch args git-substatus args color codes printed
--color --color false
--color --no-color false
`` --color true
`` --no-color false

Fix 'gone' status when pulling an empty repo from the remote

Actual behavior

Pulling an empty repository from upstream creates a status "gone".

To reproduce:

mkdir /tmp/gs-test
cd /tmp/gs-test
mkdir bar-upstream && cd bar-upstream
git init --bare # remote must be 'bare'
cd ..
git clone bar-upstream bar
mkdir foo && cd foo
git init
cd ..
git-substatus
#  directory: </tmp/gs-test>
# • bar  master  gone
# • foo  master  <sync>
cd bar
git status -sb
## No commits yet on master...origin/master [gone]

Expected behavior

The status should instead be called <sync> because there are no changes.

Relicense project

git-substatus is currently licensed with GPL-3.0, introduced sometime like three years ago. I read that GPL-3 isn't very much OK in the industry. It may be better to change it to a much more permissive license, like MIT. No need to hassle.

- [ ] Ask approval from contributors

Add --json flag

Add --json flag to the CLI to print the output as JSON so some tools like jq can be used to extract structured information.

Use more async operations

It might be a better user experience, performance if git-substatus uses more of async operations for, such as:

  • fetching

etc.

Create Dockerfile

In order to run git-substatus with Docker, create a Dockerfile and post to https://hub.docker.com/

  • Create Dockerfile in the repo
FROM python:3.8-alpine
LABEL MAINTAINER="strboul"
LABEL REPOSITORY="https://github.com/strboul/git-substatus"
LABEL HOMEPAGE="https://github.com/strboul/git-substatus"
COPY setup.py git-substatus/ .
RUN pip install . # or make install
  • Update README
docker run -t -v "$(pwd)":/repo strboul/git-substatus:latest

Also possible to add an alias in the .bashrc or .zshrc.

Optional:

Show remote url while fetching

git-substatus currently prints the folder name while fetching from remote. It'll be more useful to print the remote url instead.

git-substatus --fetch
Fetching from remote "[email protected]:strboul/git-substatus.git"
Fetching from remote "[email protected]:strboul/kwic-ts.git"

Notes:

  • may use git config --get remote.origin.url to get the remote url.

  • If git config --get remote.origin.url returns non-zero, it means it doesn't have a remote, so don't fetch it, but show a message such as Can't fetch "<folder>" as remote not exist.

  • Remove All fetched. message.

Truncate names in output

Truncate the names in the output, including:

  • repo,
  • branch,
  • status,
  • stash,
  • worktree status,
  • etc.

If the name is greater than n, e.g. 16 characters, get the first n chars and put use Unicode horizontal ellipsis (U+2026) on the 17th char to imply that the branch name is actually truncated.

TODO

  • argument --no-truncated-names that shows the full names always.

KeyError: 'Unknown status mapping: "RM"'

I'm trying on the home directory where my projects.

Python version: 3.9.2
git-substatus version: 0.2.3

[ 12:57 ÖS ] [ adil@debian:~/Projects ]
 $ git-substatus 
Traceback (most recent call last):
  File "/usr/local/bin/git-substatus", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/__main__.py", line 11, in main
    GitSubstatusApplication(args).exec()
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/gitsubstatus.py", line 59, in exec
    statuses = status.get_status()
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 149, in get_status
    git_status = tuple(self.__get_statuses())
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 154, in __get_statuses
    status = self.__get_git_status(repo)
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 164, in __get_git_status
    self.status_changes = StatusChanges.get_status_changes(self.status_details)
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 42, in get_status_changes
    cls.mapped_status_count = cls.__get_mapped_status_count()
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 105, in __get_mapped_status_count
    return dict(status_count_gen())
  File "/usr/local/lib/python3.9/dist-packages/git_substatus/status.py", line 100, in status_count_gen
    raise KeyError(f"Unknown status mapping: \"{k}\"")
KeyError: 'Unknown status mapping: "RM"'

Auto fetching

  • Asynchronous fetching operation: fetching should be as fast as possible. (Need to resolve #22)

  • If fetching isn't fast enough, do it in the background in a forked process invoked when the command is called.

  • The time is Realtime Timer, not Monotonic, (borrowing here the nomenclature of systemd-timer), so the time is always ticking even when the machine is powered off.

Need to check the date and internal storage that auto-fetch has been done. For internal storage, maybe choose a path like ~/.config/git-substatus/state.json.

# state.json file (mirroring the data structure of config.json)
{
  "autoFetchHooks": [
    {
      "folders": ["/path/to/folder1", "path/to/folder2"],
      "lastRunDate": "2023-01-...", # last command run with autofetchhooks modified.
    }
  ]
}

Pseudocode.

if config.autoFetchHooks.minutes:
  if (now() > state.autoFetchHooks.lastRunDate
      and now + config.autofetchHooks.minutes > state.autoFetchHooks.lastRunDate):
    args.append('--fetch')
 

Create a config entry. (Need to resolve #7)

autoFetchHooks:
    minutes: 60 # after login, after every x minutes, command will be run with the `--fetch` flag. Only positive integers are allowed. Minimum value is `1`.

Show different color and/or add a symbol to the branch column unless it shows the default

Show a different color and/or add a symbol to the branch column (like *) unless it shows the default branch name (mostly master, main, release etc.).

Unfortunately, this issue is a bit complex as there's no standard way of getting the default branch name right away.


Programmatically, it's possible to get the branch name in multiple ways:

1. If default branch is set in git config

git config --get init.defaultBranch

2. If the repo was downloaded with git clone

then origin/HEAD is set automatically.

git symbolic-ref refs/remotes/origin/HEAD | cut -d '/' -f4
master
git rev-parse --abbrev-ref origin/HEAD
origin/master

3. Get from the remote

git ls-remote --symref origin HEAD
ref: refs/heads/master  HEAD
28c8d9f868eb9af98618407170da6a63c43e7f62        HEAD

git ls-remote --symref origin HEAD
ref: refs/heads/main    HEAD
597b74a4a04c8741db1000901627745b65e5d69a        HEAD

The problem with this way is: It takes a while to get this from remote, like (~ 2000ms) so it's better
to create a cache file in the home directory (e.g. $HOME/.cache/git-substatus/cache.json)
to make the process faster.

Example cache file:

{
  "cache": [
    {
      "repository": "git-substatus",
      "defaultBranch": "master",
      "cacheTime": "1631264137"
    },
    {
      "repository": "test",
      "default-branch": "main",
      "cacheTime": "1631264137"
    }
  ]
}

The risk of caching is that the repository name isn't failproof as it may be replaced with another repository having the same name. That's why need to find a unique identifier for it?

The caching invalidation can happen every week (168h) and on every time when git-substatus is called with the --fetch option.


TODO:

  • Detect default branch in a repository
  • Display a visual cue if it's checked out to a non default branch
  • Write unit tests (e.g. repos which default branch name isn't master)
  • (Optional) Implement a caching mechanism to retrieve default branch information faster

Add pull flag

Like --fetch, add a --pull flag to be able to pull the repos in batch.

Allow multiple dirs and subdirs

It can be useful to check the git status of the multiple dirs.

git-substatus ~/dir1 ~/dir2

It's also good to check the multiple sub-dirs (but cannot check dirs and sub-dirs at the same time).

git-substatus ~/dir1 ~/dir2 --subdirs

Think a bit more about how dirs and subdirs should be printed on the terminal.

Extra use case:

If you git track the system folders like /etc (via a tool like etckeeper) or ~/.config,
there can be a script written to get a git status of those folders such as:

system_git_status() {
  git-substatus --subdirs=\
    /etc, \
    "${XDG_CONFIG_HOME:-~/.config}", \
    "${XDG_DATA_HOME:-~/.local/share}" \
    --include-hidden
}

Set up a config file for the persistent options

  • Create a config file (e.g. $HOME/.config/git-substatus/config.json) for some options.

If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.

For example:

{
  "styles": {
    "repository": {
      "color": "blue",
      "emphasis": "bold"
    },
    "stash": {
      "color": "green"
    }
  },
  "components": {
     "item_bullet": "",
     "display": {
       "directory": true,
       "branch": true,
       "stash": false
     }
  }
}

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.