Post

Learning GitHub from Basics (3) - Improving Efficiency with Custom Commands

Custom commands that can reduce 1 second

Learning GitHub from Basics (3) - Improving Efficiency with Custom Commands

This post has been translated from Korean to English by Gemini CLI.

This content consists of commands that can be used for efficiency in projects. If there are any incorrect contents or commands that can be added, please leave a comment or contact me at joyson5582@gmail.com!

This content continues from the previous content.

Creating Git Custom Commands

Below, before explaining, I will explain how to create custom commands in Git.

1
git config --global alias.st "status"

You can specify it as a command like this.

1
2
[alias]
	st = status

You can also specify it directly in the git file mentioned in the first part.

Using Git Log

550

When git log is called, it is detailed, but you cannot see summarized or meaningful values.

1
git log --pretty=format:'%C(blue)%h %C(black)%s %C(magenta)(%cr)%C(bold green) %an'

What happens if you run this command?

600

It appears concisely, as shown above.

To explain the options: %C(<color>): Specifies the color. %h: Short commit hash value (%H is the long hash value). %s: Commit message subject. %an: Author’s name (at this time, our project automatically generates it with github-action, so it appears like that). %cr: Commit time (relative time). It is composed like this. (There are various attributes, so you can output logs as needed - refer to git log pretty format)

Then, referring to Creating Git Custom Commands above, git config --global alias.l "log --pretty=format:'%C(blue)%h %C(black)%s %C(magenta)(%cr)%C(bold green) %an'" When l` is entered, it becomes the above command.

Let’s use these commands more professionally here.

git l -p backend/src/main/java/corea/feedback/controller/UserFeedbackControllerSpecification.java

Fetches commits where the file has changed. (-p also includes the changed body).

git l -S '@Profile("dev")'

Fetches commits where the change @Profile("dev") occurred in the file.

git l --author="youngsu5582

Fetches commits where the commit author is youngsu5582.

In this way, you can cleanly perform additional searches based on custom commands.

1
2
3
4
5
6
7
8
reverse = "!f() { \
	if [ -z \"$1\" ]; then \
		l --reverse -n 4 \
	else \
		l --reverse -n ${1} \
	fi; \
	unset -f f; \
}; f"

Additionally, you can execute functions using !f(). If there are no parameters? (if statement) -> Output 4 in reverse. If there are parameters? (else statement) -> Output as many as the number of parameters.

600

It is also possible to input additional parameters like this.

Create if branch does not exist / Move if branch exists

Generally, To create a branch? -> git checkout -b XXX, git switch -c XXX To move a branch? -> git checkout XXX, git switch XXX Perform as above.

Difference between checkout and switch?

Checkout is used for various purposes such as branch switching, commit checkout (reverting), etc. Switch can only switch branches. -> It’s better to use switch if possible.

And, if you try to create an already existing branch? fatal: a branch named 'be_dev_deploy' already exists It warns that it already exists.

You might have felt the inconvenience of being confused about whether it already exists, or wanting to move regardless of that. (I certainly felt it ㅇ.ㅇ..)

1
2
3
4
5
6
7
8
 sw = "!f() { \
		if git show-ref --verify --quiet refs.heads/$1; then \
		   git switch $1; \
		else \
		 git switch -c $1; \
		fi; \
		unset -f f; \
}; f"

If you execute the above command, it moves if it exists + creates and moves if it doesn’t exist. How does the git show-ref --verify --quiet refs/heads/XXX command detect it?

  • git show-ref GPT says shows all references in the repository. Simply put, it’s convenient to think of it as showing pointers to information related to the repository.
    1
    2
    3
    4
    5
    6
    7
    
    git show-ref
    ec3c0af519649fc8175a18719f11094d1f4582c0 refs/heads/be_dev_deploy
    3922afc79a6a8fd1eedc0e34b9f1979af5abf7f4 refs/heads/develop
    931a51c702a464494c36252d65f9935ff2b3370f refs/heads/feat/#302
    e74920a56c5a86769aaf7239d88181680308a5b refs/remotes/origin/test_deploy
    689e0178030b56439bb1d152ae992fcb5622f2a4 refs/stash
    87c30e5bdd46f5d2a337ba2d019c5200740d40e3 refs/tags/v1.0.0
    

    It shows branches, branches existing in remotes, tags, etc. If it doesn’t exist, --verify causes fatal, and quiet does not generate a result.

How does it detect if it doesn’t generate a result? Commands executed within an if statement are designed to return a status code. 0 for success, 1 for failure. -> fatal returns 1.

refs/heads

What is refs/heads? Literally, it’s the branch where branches are stored. You can check it yourself. Like cd .git/refs/heads

600

600

Folders are created with / as the separator. (feat/#311 -> feat + #311) These files cannot be viewed or touched directly. Work can be done through show-ref or update-ref. (When we push or fetch commits, these values change.)

In conclusion, If a branch exists, it moves; if a branch does not exist, it is created!

Convenience Commands

As for the rest, I looked for more, but they didn’t feel revolutionary, just convenient commands. Is it like IntelliJ shortcuts?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
l = log --pretty=format:'%C(blue)%h %C(black)%s %C(magenta)(%cr)%C(bold green) %an'
last = "l -1 HEAD"
s = "status"
b = "branch -v"
ob = "branch -rv"
delete = "branch -D"
undo = "reset --soft HEAD~1"
ps = push origin HEAD
head = rev-parse --abbrev-ref HEAD
rbd = git pull origin develop --rebase

reverse = "!f() { \
                if [ -z \"$1\" ]; then \
                 git l --reverse -n 4; \
                else \
                 git l --reverse -n ${1}; \
                fi; \
                unset -f f; \
         }; f"

sw = "!f() { \
			if git show-ref --verify --quiet refs.heads/$1; then \
			   git switch $1; \
			else \
			 git switch -c $1; \
			fi; \
			unset -f f; \
		}; f"

This should be about it. It’s very trivial, but if it can reduce even 0.1 seconds of repetition, isn’t it meaningful?

Various commands will be possible. (It’s possible to receive additional parameters and execute functions.) It would be good to create and spread elements that team members would find convenient in each project.

```

This post is licensed under CC BY 4.0 by the author.