Search This Blog

Thursday, February 17, 2022

Git Internals

Git is a content-addressable filesystem where objects are stored as simple key-values, which means you can pass any kind of content into Git and you will get a key that will allow you to retrieve the content.

The key of the object is going to be a 40-character SHA-1 checksum hash (It can be simulated by git hash-object command).

Git objects can be of the below 3 types:

1 - Blob - Zlib Compressed Header and File Content

2 - Tree -  One or more entries, each of which is the SHA-1 hash of a blob or subtree with its associated mode, type, and filename. 

4 - Commit - Top Level Tree, Parent Commit, Author and Commit Description

Git stores the objects inside .git/objects within subdirectories which is named with the first 2 characters of the SHA-1, and the filename is the remaining 38 characters.

git cat-file command is sort of a Swiss army knife for inspecting Git objects.

git cat-file -t [hash] gives the type of the object.

git cat-file -t [hash] will print the content of the object.

While working with git [hash] can be given as only first n chars (depending upon the size of the project) only rather than copying the whole 40 chars.

"Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique." - Source

Source: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects

Tuesday, October 12, 2021

Reverse the files

tac command is reverse of cat. It writes each file to stdout, last line first.

If you want to reverse the whole file in vim you can do it by :%!tac 

Sunday, October 3, 2021

Find number of lines selected in visual mode

Command: 𝐠 𝐂𝐓𝐑𝐋-𝐆.

					*g_CTRL-G* *word-count* *byte-count*
g CTRL-G		Prints the current position of the cursor in five
			ways: Column, Line, Word, Character and Byte.  If the
			number of Characters and Bytes is the same then the
			Character position is omitted.
			If there are characters in the line that take more
			than one position on the screen (<Tab> or special
			character), both the "real" column and the screen
			column are shown, separated with a dash.
			See also 'ruler' option.  {not in Vi}


							*v_g_CTRL-G*
{Visual}g CTRL-G	Similar to "g CTRL-G", but Word, Character, Line, and
			Byte counts for the visually selected region are
			displayed.
			In Blockwise mode, Column count is also shown.  (For
			{Visual} see |Visual-mode|.)
			{not in VI}

Sunday, January 31, 2021

Pause Resume Terminal Output

Suppose there is a stream of output being printed in the terminal and you want to pause it to read or to capture the screenshot you can try 𝐂𝐭𝐫𝐥 + 𝐒 (XOFF control command) to freeze the output it can be resumed by 𝐂𝐭𝐫𝐥 + 𝐐 (XON Control Command)

Switching Linux XON/OFF Flow Control:

  • To enable: 𝐬𝐭𝐭𝐲 𝐢𝐱𝐨𝐧
  • To disable: 𝐬𝐭𝐭𝐲 -𝐢𝐱𝐨𝐧

"Long before there were computers, there were teleprinters (a.k.a. teletypewriters, a.k.a. teletypes). Think of them as roughly the same technology as a telegraph, but with some type of keyboard and some type of printer attached to them.

Because teletypes already existed when computers were first being built, and because computers at the time were room-sized, teletypes became a convenient user interface to the first computers – type in a command, hit the send button, wait for a while, and the output of the command is printed to a sheet of paper in front of you.

Software flow control originated around this era – if the printer couldn't print as fast as the teletype was receiving data, for instance, the teletype could send an XOFF flow control command (Ctrl+S) to the remote side saying "Stop transmitting for now", and then could send the XON flow control command (Ctrl+Q) to the remote side saying "I've caught up, please continue".

And this usage survives in Unix because modern terminal emulators are emulating physical terminals (like the vt100) which themselves were (in some ways) emulating teletypes."

Tuesday, January 26, 2021

Insert a file or the result from running an external program into the vim opened file

Suppose you have a file open in the vim and you want to insert output of some shell command into the file instead of closing the file or leaving the current terminal :read can be utilized to directly append the output of shell command into the file.

The :read command can insert a file or the result from running an external program into the current buffer. In case of the shell command it has to be prefixed with the !

Examples:

:read !openssl rand -hex 32 :read /etc/passwd

Thursday, November 26, 2020

Getting top contributors of given directory based on commit counts

git log --pretty=format:"%an%x09" dir | sort | uniq -c | sort -nr

git log --pretty option prints the contents of the commit logs in a given format (%an%x09b) for given directory, here %an is placeholder for Author Name and %x09 is placeholder for tab.

Output of first command will be series of author names of commits affecting given directory ordered by date.

Since we are not concerned with order we will just sort the output so that we can easily group the names using uniq -c which along with unique values prints the count.

Now the output is in alphabetical order of Author Names if we want to order by count of commits we can pipe it to sort -nr  where n represents sort by numerical value and r represents sort in reverse order.

Sunday, April 26, 2020

Using set command for temporarily disabling shell history

set is used to change the value of shell attributes and positional parameters, or display the names and values of shell variables.

If you are executing a command which contains your password or some other sensitive details and you don't want it logged in command history you can turn off history logging by

$ set +o history

To check whether history is turned off you can execute
$ set -o | grep history
history         off

You can turn it back on by executing 

$ set -o history

Sunday, February 9, 2020

Linux Command History

How to command history is saved in Linux
Command history is saved in .bash_history file by history command.

Customization :
1 - Location
You can change history file location of by overwriting HISTFILE

2 - Time
By default, history doesn't store the time of command execution you can provide HISTTIMEFORMAT to store it

    # for storing the date in history in %Y-%M-%D %HH:%MM:%SS
    export HISTTIMEFORMAT="%F %T: "

3 - History limit
The default size of history is 500 you can increase by overwriting the following variables

    # .bash_history file events limit
    export HISTFILESIZE=20000

    # history command events limit
    export HISTSIZE=10000

Productivity Hack: Use CTRL + R to cycle through history to reuse previously executed command rather than finding by clicking up arrow repeatedly.

Problem: If you are using multiple ssh or tmux sessions, and CTRL + R won't display other sessions command because history is not dumped in the file unless a session is closed gracefully.
There is also the chance of losing history on abruptly closing sessions.
Hack: http://northernmost.org/blog/flush-bash_history-after-each-command/

    export PROMPT_COMMAND='history -a'

Explanation:
history -a appends the current history buffer in .bash_history file
The value of the variable  PROMPT_COMMAND  is examined just before Bash prints each primary prompt (PS1).
PS1  is the primary prompt which is displayed before each command

    [ash-ishh@xBot ~]$ echo $PS1
    [\u@\h \W]\$

If  PROMPT_COMMAND is set and has a non-null value, then the value is executed just as if it had been typed on the command line.

List of possible escape sequences: https://www.gnu.org/software/bash/manual/html_node/Controlling-the-Prompt.html

Thursday, January 23, 2020

Delete matched line with range in vim

You can use . to refer to the current line.

1) :g/foo/.,+2d will delete line with text foo and 2 lines after it

2) :g/foo/-3,.d will delete line with text foo and 3 lines before it

3) :g/foo/-1,+1d will delete line with foo, one line before it and one line after it

vim go to the definition

In vim rather than searching for the function definition or variable initialization you can type gd in command mode which will go to the local declaration of the word where cursor is type gD if you want to go to the global declaration.

Sunday, October 13, 2019

Remove lines using vim

To remove all the lines in vim that contain certain string execute:
:g/string/d

To do the opposite i.e remove the lines that do not contain certain string execute:
:v/string/d

Saturday, July 27, 2019

dd

dd is a command-line utility for Unix and Unix-like operating systems, the primary purpose of which is to convert and copy files.
dd stands for copy and convert (called dd because cc is already in use by C compiler).

[Options]
bs : BYTES read and write up to BYTES bytes at a time (default: 512)
if : FILE read from FILE instead of stdin
of : FILE write to FILE instead of stdout
status : LEVEL The LEVEL of information to print to stderr; 'none' suppresses everything but error messages, 'noxfer' suppresses the final transfer statistics, 'progress' shows periodic transfer statistics

[Examples]
1 - Wipe the disk partition
# dd if=/dev/zero out=/dev/sd<?><n>

2  - Make USB stick bootable
Step 1 : Find device name of USB stick using lsblk
Step 2 : Copy ISO
# dd if=/home/user/download/arch.iso of=/dev/sd<?> status=progress

? = disk name
n = partition number

Reverse of making USB stick bootable
# dd if=/dev/sd<?> of=backup.iso status=progess

Above command can be used to create single image of stick containing all the partitions/data which then can be restored on another machine by simply mounting image using
# mount backup.iso /mnt/pd -o loop