Thursday, March 9, 2023

Git ignore

 Git sees every file in your working copy as one of three things:

  1. tracked - a file which has been previously staged or committed;
  2. untracked - a file which has not been staged or committed; or
  3. ignored - a file which Git has been explicitly told to ignore.

Ignored files are usually build artifacts and machine generated files that can be derived from your repository source or should otherwise not be committed. Some common examples are:

  • dependency caches, such as the contents of /node_modules or /packages
  • compiled code, such as .o, .pyc, and .class files
  • build output directories, such as /bin, /out, or /target
  • files generated at runtime, such as .log, .lock, or .tmp
  • hidden system files, such as .DS_Store or Thumbs.db
  • personal IDE config files, such as .idea/workspace.xml

Ignored files are tracked in a special file named .gitignore that is checked in at the root of your repository. There is no explicit git ignore command: instead the .gitignore file must be edited and committed by hand when you have new files that you wish to ignore. .gitignore files contain patterns that are matched against file names in your repository to determine whether or not they should be ignored.

Git ignore patterns

.gitignore uses globbing patterns to match against file names. You can construct your patterns using various symbols:

PatternExample matchesExplanation*
**/logslogs/debug.log
logs/monday/foo.bar
build/logs/debug.log
You can prepend a pattern with a double asterisk to match directories anywhere in the repository.
**/logs/debug.loglogs/debug.log
build/logs/debug.log
but not
logs/build/debug.log
You can also use a double asterisk to match files based on their name and the name of their parent directory.
*.logdebug.log
foo.log
.log
logs/debug.log
An asterisk is a wildcard that matches zero or more characters.
*.log
!important.log
debug.log
trace.log
but not
important.log
logs/important.log
Prepending an exclamation mark to a pattern negates it. If a file matches a pattern, but also matches a negating pattern defined later in the file, it will not be ignored.
*.log
!important/*.log
trace.*
debug.log
important/trace.log
but not
important/debug.log
Patterns defined after a negating pattern will re-ignore any previously negated files.
/debug.logdebug.log
but not
logs/debug.log
Prepending a slash matches files only in the repository root.
debug.logdebug.log
logs/debug.log
By default, patterns match files in any directory
debug?.logdebug0.log
debugg.log
but not
debug10.log
A question mark matches exactly one character.
debug[0-9].logdebug0.log
debug1.log
but not
debug10.log
Square brackets can also be used to match a single character from a specified range.
debug[01].logdebug0.log
debug1.log
but not
debug2.log
debug01.log
Square brackets match a single character form the specified set.
debug[!01].logdebug2.log
but not
debug0.log
debug1.log
debug01.log
An exclamation mark can be used to match any character except one from the specified set.
debug[a-z].logdebuga.log
debugb.log
but not
debug1.log
Ranges can be numeric or alphabetic.
logslogs
logs/debug.log
logs/latest/foo.bar
build/logs
build/logs/debug.log
If you don't append a slash, the pattern will match both files and the contents of directories with that name. In the example matches on the left, both directories and files named logs are ignored
logs/logs/debug.log
logs/latest/foo.bar
build/logs/foo.bar
build/logs/latest/debug.log
Appending a slash indicates the pattern is a directory. The entire contents of any directory in the repository matching that name – including all of its files and subdirectories – will be ignored
logs/
!logs/important.log
logs/debug.log
logs/important.log
Wait a minute! Shouldn't logs/important.log be negated in the example on the left

Nope! Due to a performance-related quirk in Git, you can not negate a file that is ignored due to a pattern matching a directory
logs/**/debug.loglogs/debug.log
logs/monday/debug.log
logs/monday/pm/debug.log
A double asterisk matches zero or more directories.
logs/*day/debug.loglogs/monday/debug.log
logs/tuesday/debug.log
but not
logs/latest/debug.log
Wildcards can be used in directory names as well.
logs/debug.loglogs/debug.log
but not
debug.log
build/logs/debug.log
Patterns specifying a file in a particular directory are relative to the repository root. (You can prepend a slash if you like, but it doesn't do anything special.)

** these explanations assume your .gitignore file is in the top level directory of your repository, as is the convention. If your repository has multiple .gitignore files, simply mentally replace "repository root" with "directory containing the .gitignore file" (and consider unifying them, for the sanity of your team).*

In addition to these characters, you can use # to include comments in your .gitignore file:

# ignore all logs
*.log

You can use \ to escape .gitignore pattern characters if you have files or directories containing them:

# ignore the file literally named foo[01].txt
foo\[01\].txt

Shared .gitignore files in your repository

Git ignore rules are usually defined in a .gitignore file at the root of your repository. However, you can choose to define multiple .gitignore files in different directories in your repository. Each pattern in a particular .gitignore file is tested relative to the directory containing that file. However the convention, and simplest approach, is to define a single .gitignore file in the root. As your .gitignore file is checked in, it is versioned like any other file in your repository and shared with your teammates when you push. Typically you should only include patterns in .gitignore that will benefit other users of the repository.

Personal Git ignore rules

You can also define personal ignore patterns for a particular repository in a special file at .git/info/exclude. These are not versioned, and not distributed with your repository, so it's an appropriate place to include patterns that will likely only benefit you. For example if you have a custom logging setup, or special development tools that produce files in your repository's working directory, you could consider adding them to .git/info/exclude to prevent them from being accidentally committed to your repository.

Global Git ignore rules

In addition, you can define global Git ignore patterns for all repositories on your local system by setting the Git core.excludesFile property. You'll have to create this file yourself. If you're unsure where to put your global .gitignore file, your home directory isn't a bad choice (and makes it easy to find later). Once you've created the file, you'll need to configure its location with git config:

$ touch ~/.gitignore
$ git config --global core.excludesFile ~/.gitignore

You should be careful what patterns you choose to globally ignore, as different file types are relevant for different projects. Special operating system files (e.g. .DS_Store and thumbs.db) or temporary files created by some developer tools are typical candidates for ignoring globally.

Ignoring a previously committed file

If you want to ignore a file that you've committed in the past, you'll need to delete the file from your repository and then add a .gitignore rule for it. Using the --cached option with git rm means that the file will be deleted from your repository, but will remain in your working directory as an ignored file.

$ echo debug.log >> .gitignore
  
$ git rm --cached debug.log
rm 'debug.log'
  
$ git commit -m "Start ignoring debug.log"

You can omit the --cached option if you want to delete the file from both the repository and your local file system.

Committing an ignored file

It is possible to force an ignored file to be committed to the repository using the -f (or --force) option with git add:

$ cat .gitignore
*.log
  
$ git add -f debug.log
  
$ git commit -m "Force adding debug.log"

You might consider doing this if you have a general pattern (like *.log) defined, but you want to commit a specific file. However a better solution is to define an exception to the general rule:

$ echo !debug.log >> .gitignore
  
$ cat .gitignore
*.log
!debug.log
  
$ git add debug.log
  
$ git commit -m "Adding debug.log"

This approach is more obvious, and less confusing, for your teammates.

Stashing an ignored file

git stash is a powerful Git feature for temporarily shelving and reverting local changes, allowing you to re-apply them later on. As you'd expect, by default git stash ignores ignored files and only stashes changes to files that are tracked by Git. However, you can invoke git stash with the --all option to stash changes to ignored and untracked files as well.

Debugging .gitignore files

If you have complicated .gitignore patterns, or patterns spread over multiple .gitignore files, it can be difficult to track down why a particular file is being ignored. You can use the git check-ignore command with the -v (or --verbose) option to determine which pattern is causing a particular file to be ignored:

$ git check-ignore -v debug.log
.gitignore:3:*.log  debug.log

The output shows:

<file containing the pattern> : <line number of the pattern> : <pattern>    <file name>

You can pass multiple file names to git check-ignore if you like, and the names themselves don't even have to correspond to files that exist in your repository.

Source

Drop all tables in mysql

This sql clause will generate drop clauses

SELECT concat('DROP TABLE IF EXISTS `', table_name, '`;') FROM information_schema.tables WHERE table_schema = 'MyDatabaseName';

Get result and paste to command line

Monday, December 12, 2022

SUDO COMMAND ALIAS

 Usage of sudo command alias and it various useful features with examples given.

Syntax

                Cmnd_Alias        NAME   =   cmnd1, cmnd2, cmnd3 ….

To define command alias in sudoers file must remember two hard coded rules

  1. Alias name should be defined in uppercase letters and can contain number, alphabet and underscore (_). Alias name must start with alphabet.

                NAME = [A-Z]([A-Z][0-9]_)

  1. Commands must be specified in absolute path format.

Command alias can be mapped to either user or group.

Example1

User “romeo” should be able to create new user and password.

               ROMEO_CMDS  =  /usr/sbin/useradd, /usr/bin/passwd

               romeo                  ALL =  (ALL)         ROMEO_CMDS

Here mentioning relative path or just direct command (passwd, useradd) will make sudo non-functional.

The same can be defined using user id by adding hash (#) as prefix.

               #502      ALL = (ALL)          ROMEO_CMDS

Example2

Grant same privileges to group “tree”

               %tree    ALL = (ALL)          ROMEO_CMDS

Advanced option

Grant access to execute all the commands in a directory. Directory name must be full path and should end with slash (/). The trailing slash used by system to identify either it is a command or directory.

                Cmnd_Alias        APP_CMDS = /opt/was/bin/

Multiple different command aliases can be defined at once using colon (:)

               Cmnd_Alias        APP_CMDS =  /usr/bin/passwd, /sbin/service httpd *, /sbin/ifconfig : DB_CMDS = /bin/su – oracle, /home/oracle/crsstart : ADMIN_CMDS = /sbin/, /usr/sbin/

               %app1                   ALL = (ALL)          APP_CMDS

               dbuser                  ALL = (ALL)          DB_CMDS

               %admins              ALL = (ALL)          ADMIN_CMDS

Use exclamation (!) symbol for negative notation.

Placing commands inside double quote (“) says strictly stick with command and do not accept any argument.

                  mala      ALL = (ALL)          /sbin/, ! /sbin/init

Here user mala allowed running any command inside /sbin directory but not “init”.

                  fry          ALL = (root)        /bin/su [!-]*[!root]*

Using exclamation symbol can restrict at argument level. Above allows user fry to run /bin/su command with root privileges. Same time it restricts using any options/argument and login to root.

One command alias can be referred into another command alias.

                  Cmnd_Alias        SUN =      /usr/bin/passwd

                  Cmnd_Alias        SWE =      /usr/sbin/useradd, SUN

To say sudo to should not accept any argument but only just execute command, append double quote at end. (“”)
                  swe        ALL = (ALL)          /sbin/hwclock “”
User swe can see hardware clock time but will not be able to modify any settings.

Monday, August 23, 2021

Nagios + check load average

Though its an old post, replying now because I knew check_load threshold values are bigtime headache for the newbies.. ;)

A warning alert, if CPU is 70% for 5min, 60% for 10mins, 50% for 15mins. A critical alert, if CPU is 90% for 5min, 80% for 10mins, 70% for 15mins.

*command[check_load]=/usr/local/nagios/libexec/check_load -w 0.7,0.6,0.5 -c 0.9,0.8,0.7*

All my findings about CPU load:

Whats meant by "the load": Wikipedia says:

All Unix and Unix-like systems generate a metric of three "load average" numbers in the kernel. Users can easily query the current result from a Unix shell by running the uptime command:

$ uptime
14:34:03 up 10:43,  4 users,  load average: 0.06, 0.11, 0.09

From the above output load average: 0.06, 0.11, 0.09 means (on a single-CPU system):

  • during the last minute, the CPU was underloaded by 6%
  • during the last 5 minutes, the CPU was underloaded 11%
  • during the last 15 minutes, the CPU was underloaded 9%

.

$ uptime
14:34:03 up 10:43,  4 users,  load average: 1.73, 0.50, 7.98

The above load average of 1.73 0.50 7.98 on a single-CPU system as:

  • during the last minute, the CPU was overloaded by 73% (1 CPU with 1.73 runnable processes, so that 0.73 processes had to wait for a turn)
  • during the last 5 minutes, the CPU was underloaded 50% (no processes had to wait for a turn)
  • during the last 15 minutes, the CPU was overloaded 698% (1 CPU with 7.98 runnable processes, so that 6.98 processes had to wait for a turn)

Nagios threshold value calculation:

For Nagios CPU Load setup, which includes warning and critical:

y = c * p / 100

Where: y = nagios value c = number of cores p = wanted load procent

for a 4 core system:

time      5 min  10 min    15 min
warning:  90%    70%       50%
critical: 100%   80%       60%

command[check_load]=/usr/local/nagios/libexec/check_load -w 3.6,2.8,2.0 -c 4.0,3.2,2.4

For a single core system:

y = p / 100

Where: y = nagios value p = wanted load procent

time       5 min  10 min    15 min
warning:   70%    60%       50%
critical:  90%    80%       70%

command[check_load]=/usr/local/nagios/libexec/check_load -w 0.7,0.6,0.5 -c 0.9,0.8,0.7

A great white paper about CPU Load analysis by Dr. Gunther http://www.teamquest.com/pdfs/whitepaper/ldavg1.pdf In this online article Dr. Gunther digs down into the UNIX kernel to find out how load averages (the “LA Triplets”) are calculated and how appropriate they are as capacity planning metrics.

Monday, April 12, 2021

Python3 find string

 


from datetime import datetime


def f1(s,r):
t1 = datetime.utcnow()
if r in s:
t2 = datetime.utcnow()
delta = t2 - t1
print(f'found in {delta.total_seconds()}')
else:
t2 = datetime.utcnow()
delta = t2 - t1
print(f'Not found in {delta.total_seconds()}')


def f2(s,r):
t1 = datetime.utcnow()
idx = s.find(r)
t2 = datetime.utcnow()
delta = t2 - t1
if idx > 0:
print(f'found in {delta.total_seconds()}')
else:
print(f'Not found in {delta.total_seconds()}')


if '__main__' == __name__:
s1 = '1'*10000
s2 = 'abc def ghi jkl mno pqr stu vwx yz'
s3 = '3'*10000
s = f'{s1} {s2} {s3}'
f1(s, 'ghi jkl')
f2(s, 'ghi jkl')


Kết quả cho thấy hàm str.find() tìm kiếm nhanh hơn.


Git, Gitlab command

Using ssh to access repository

- Create a key pair
- Copy/paste the public key content to github.com
- Run the following commands before clone source code
    eval $(ssh-agent)
    ssh-add ~/.ssh/private_key
- Clone source code

Create

  • Create new local repository
    • git init
  • Clone an existing repository
    • gitdone ssh://user@domain.com/repo.git

Local Changes

  • Changed files in your working dir
    • git status
  • Changes to tracked file
    • git diff
  • Add all current changes to next commit
    • git add .
  • Add some changes in <file> to next commit
    • git add -p <file>
  • Commit all local changes in tracked file
    • git commit -a
  • Commit previous staged changes
    • git commit
  • Change the last commit
    • git commit --amend

Commit history

  • Show all commit, starting with newest
    • git log
  • Show changes over time for a specific file
    • git log -p <file>
  • Who change what and when in <file>
    • git blame <file>

Branches and Tags

  • List all existing braches
    • git branch -av
  • Switch HEAD branch
    • git checkout <branch>
  • Create a new branch based on current HEAD
    • git branch <new-branch>
  • Create a new tracking branch based on a remote branch
    • git checkout --track <remote/branch> 
  • Delete a local branch
    • git branch -d <branch>
  • Mark the current commit with a tag
    • git tag <tag-name>

Update & Publish

  • List all currently configured remotes
    • git remote -v
  • Show info about remote
    • git remote show <remote>
  • Add new remote repository, named <remote>
    • git remote add <short name> <url>
  • Download all changes from <remote>, but don't integrate into HEAD
    • git fetch <remote>
  • Download changes and directly merge/integrate into HEAD
    • git pull <remote> <branch>
  • Publish local changes on a remote
    • git push <remote> <branch>
  • Delete a branch on the remote
    • git branch -dr <remote/branch>
  • Publish your tags
    • git push --tags

Merge and rebase

  • Merge branch into current HEAD
    • git merge <branch>
  • Rebase your current HEAD onto <branch>
    • git rebase <branch>
  • Abort a rebase
    • git rebase --abort
  • Continue a rebase after resolving conflicts
    • git rebase --continue
  • Use your configured merge tool to resolve conflicts
    • git mergetool
  • Use your editor to manually resolve conflicts and (alter resolving) mark file as resolved
    • git add <resolved-file>
    • git rm <resolved-file>

Undo

  • Discard all local changes in your working directory
    • git reset --hard HEAD
  • Discard local changes in specific file
    • git checkout HEAD <file>
  • Revert a commit (by producing a new commit with contrary changes)
    • git revert <commit>
  • Reset your HEAD pointer to a previous commit, ... and discard all changes since then
    • git reset --hard <commit>
  • ... and preserve all changes as untagged changes
    • git reset <commit>
  • ... and preserve uncommited local changes
    • git reset --keep <commit>

Add an existing project to Git project

1. Create new repository 
2. Open terminal and change the current working directory to your local project
3. Initialize the local directory as a Git repository
$git init
4. Add the files in your new local repository
$git add .
5. Commit the files that you've staged 
$git commit -m "First commit"
6. Copy remote repository URL
7. Add the URL for remote repository
$git remote add origin <remote_url>
8. Download all change from <remote>, but don't integrate to HEAD
$git fetch origin master:tmp
9. Rebase your current HEAD onto branch
$git rebase tmp
10. Publish local change
$git push origin HEAD:master
11. Delete branch tmp
$git branch -D tmp

Switch to branch

1. View all remote
         $git remote -v
2. Download branches
    2.1 View all branches
         $git branch -r
    2.2.1 Download all branches
         $git fetch --all
    2.2.2 Download a branch
         $git fetch <remote> <branch_name>
3. Switch to branch
         $git checkout -t <remote>/<branch_name> 

Move commits to another branch

Branch A: a1--a2--a3 (2e11c5f) --a4 (2681270) --a5 (08b0f0e)
Branch A: b1--b2--b3--b4--b5
Move commits a3 and a4 to the branch B:
1. Check out the banch A
    $git checkout A
2. Checkout the branch B
    $git checkout B
3. Move the commit a3, a4 to branch B
    $git cherry-pick 2e11c5f
    $git cherry-pick 2681270
4. Reset branch A to last commit
    $git checkout A
    $git reset --hard 08b0f0e

Override tag

Use the -f option to git tag:

-f --force

Replace an existing tag with the given name (instead of failing)
You probably want to use -f in conjunction with -a to force-create an annotated tag instead of a non-annotated one.

Example

Delete the tag on any remote before you push
  $git push origin :refs/tags/<tagname>
Replace the tag to reference the most recent commit
  $git tag -fa <tagname>
Push the tag to the remote origin
  $git push origin master --tags

Checkout pull request

pull request example: want to merge into <organization>:<branch> from <user>:<branch>

You want to checkout from <user>:<branch> but you don't have permission to access <user>:<branch>

1. checkout <organization>:<branch>
2. checkout pull request to a new branch
    $git fetch origin pull/$ID/head:<new_branch_name>
3. checkout <new_branch_name>
    $git checkout <new_branch_name>

When <user> push new commits to pull request, you want to pull these -> do again from step 1.