takeaway

Shell can be said to be a programmer’s basic skills, but in practical work, except for the students in charge of operation and maintenance, most students are not able to use it. It is enough to know ls, man, which and other commands. In fact, Shell syntax can be read in 2 hours at most, the key is to find a real scene to use it, to practice, just writing demo is certainly not enough, this is believed to be known as programmers.

The author recently studied the automation of Gitflow (see Gitflow too cumbersome? Why not automate), you need to output a script that can be used on both the front and back ends, so the Shell is the best choice. I finally had the right scenario, and I did encounter a lot of problems and learned a lot during the development process. After all, learning with problems is the most efficient. Now sort out some small achievements, hope to be helpful, I believe you will be useful in the daily development of their time.

The second one is here:# Shell hard to learn? That’s because you didn’t find scene two.

The body of the

I assume that you have some command line background, at least know pipes, Git and some basic commands.

Basic commands

Start with two basic and powerful commands: grep and xargs.

Grep is used for searching and filtering for more people familiar with it. Mainly its parameters are more, the author every time to use also need –help, probably know what it has the ability to go, with the time to check;

The xargs command is used to convert standard input to command-line arguments. For example, the following commands have the same effect.

echo "hello" | xargs git commit -m
# is equivalent to
echo "hello" | xargs sh -c 'git commit -m'
# is equivalent to
git commit -m "hello"
Copy the code

It’s a lot easier to understand. More useful is the -i parameter, which can be used to execute commands in batches. I won’t expand it here, but you can see the xargs command tutorial.

In addition, for Xargs to accept multiple inputs, the input must be processed into multiple lines, which requires a little bit of regex and another sed command:

echo "1, 2, 3" | sed 's/,/\n/g'
# 1
# 2
# 3
Copy the code

The re and sed will not be expanded here, but will suffice for the time being. At most, change the comma to the appropriate delimiter. When combined with XARgs, the effect is:

echo "1 2 3" | sed 's/ /\n/g' | xargs -I n echo "1.n.0"
# 1.1.0
# 1.2.0
# 1.3.0
Copy the code

Let’s take a look at the chemistry of these commands put together.

Quickly modify the file and commit

echo "'feat: `date`'" >> test.txt | xargs git ci -am
Copy the code

To test this, use this command to quickly generate a COMMIT.

  • Test.txt add a line: ‘feat: 2022年 01月 23日 23:28:01 CST’
  • Git log Add a new git log

If necessary, you can implement multiple commits with Xargs-I, which I did.

Multiple branches force a restore to a COMMIT

echo "master/develop/release" | sed 's/\//\n/g' | xargs -I br sh -c "git checkout br && git reset --hard 1.0.0 && git push -f"
Copy the code

This command is mainly used to restore to the initial state. Note that the “/” delimiter is used here, and for convenience, I tagged the commit to restore with 1.0.0, so that the COMMIT ID does not need to be entered.

Remove all tags except 1.0.0

Git tag | grep -v 1.0.0 | xargs -i tt sh -c"git tag -d tt; git push origin :refs/tags/tt"
Copy the code

This one is usually used in conjunction with the one above. Note the -v attribute of grep, which filters out the value after it. A slight modification of this command can also remove branches. Even local branches that do not exist remotely are automatically deleted:

Delete remote local branches that no longer exist

git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d`
Copy the code

This command is very practical. Note that there is a new command awk, which is similar to grep and has many powerful functions for processing multiple columns of text. See the Linux awk command for details. In order to ensure the rhythm of the article, here is not expanded temporarily.

Determines whether the remote has a branch

git fetch -p && git branch -r | grep -w $branchName
Copy the code

Note that the -w parameter must be added. It must match exactly.

Git rev-parse –abbrev-ref HEAD check if the current branch exists. It’s easy to write in a shell file, but a bit harder to write in a single line of command.

Get the version number of the current package.json (nodejs project)

node -p -e "require('./package.json').version"
Copy the code

You can even write a bunch of NodeJS logic between double quotes.

Get git logs between two commits and format them

git log --pretty=format:"- %cd %h - %s" $sourceBR.$targetBR --date=format:"%m/%d %H:%M"
# - 01/23 23:28 e660c5c - commit message 1
# - 01/22 23:27 758ba9a - commit message 2
Copy the code

This command is useful and can be used to automatically generate the PR fill information and format it itself. Here’s an example:

  • To get a log between develop and Master, run the$sourceBRTo develop,$targetBRI can change it to master;
  • If it’s the log between the current branch and the master, change it to$sourceBRChange to HEAD;
  • The two variables can also be commit ids

Log pretty For more format parameters, see pretty-formats.

conclusion

Finally, to a combination of the example, is the author’s actual use of a script (if you do not understand what is doing, please move to Gitflow too cumbersome? Why not automate it?

doInit() {
  echo "master/develop/release" | sed 's/\//\n/g' | xargs -I br sh -c "git checkout br && git reset --hard 1.0.0"Git tag | grep -v 1.0.0 | xargs -i tt sh -c"git tag -d tt"
}

doFeature() {
  echo "feature/featThe $1" | xargs -I ff sh -c 'git checkout develop && git checkout -b ff; echo "ff `date`" >> test.txt; git ci -am "feat: ff `date`"; git checkout develop && git rebase ff; git br -D ff'
}

doBugfix() {
  echo "bugfix/bfThe $1" | xargs -I bf sh -c 'git checkout release && git checkout -b bf; echo "bf `date`" >> bugfix.txt; git ci -am "fix: bf `date`"; git checkout release && git rebase bf; git br -D bf && git checkout develop && git rebase release'
}

doHotfix() {
  echo "hotfix/hfThe $1" | xargs -I hh sh -c 'git checkout master && git checkout -b hh; echo "hh `date`" >> hotfix.txt; git ci -am "fix: hh `date`" && npm version patch; git checkout master && git rebase hh; git br -D hh && git checkout release && git rebase master && git checkout develop && git rebase release'
}

doUAT() {
  git checkout develop && npx conventional-changelog -p angular -o CHANGELOG.md -u && git checkout release && git rebase develop
}

doDeploy() {
  git checkout release && npm version minor && git checkout master && git rebase release && git checkout develop && git rebase release
}

# doInit
# doFeature 1
# doHotfix 1
# doHotfix 2
# doFeature 2
# doUAT
# doBugfix 1
# doHotfix 3
# doBugfix 2
# doDeploy
Copy the code

The author can easily simulate a complete GitFlow workflow locally in a few seconds by opening, closing, adding, deleting and adjusting the order of the following annotations.

Of course, the author also has a more complex simulation of the simulation of real remote GitFlow workflow script, I will not post, I believe that you can already according to the above example for their own application. Especially the command that automatically generates logs, you can take a look at it, even if every time you submit a PR, manually execute it and then paste it into the PR, it looks very elegant, very decompression, isn’t it?

“You get what you do when you do the hard things. The more noisy, the more lonely; The more lonely, the richer.” – general