Git: A New Way of Managing Code

The version control system is a way to manage files/directories to track file changes so that a specific version of files can be tracked later without conflicts.

Git is one of the distributed version control systems that help in:

GitTip: Skip WorkTree

Use skip-worktree to sneak in modifications git won't notice

GitTip: Skip WorkTree

This tip is simple and powerful in equal parts. What we want to achieve is to modify a local file that git could not identify as having been modified despite being already tracked. For this example, I have a file “config.txt” with the content: “secret.” This file works well in all environments, but in the local environment, I need to change it for testing. No problem: it is modified, the relevant tests are made, it is reverted and it is uploaded.

The problem comes when that file, for various reasons, has to be modified in your local environment and has to work without being uploaded to avoid affecting other files. How can we do that?

8 Basic Git Commands Every Newbie Developer Must Know

Learn more about these essential Git commands.

Git is one of the most important parts of the developer’s day-to-day work. So learning Git is a must for a newbie developer. In this article, you are going to learn the eight most important basic Git commands.

Below, I have listed down all the eight commands. Then, we will have a look at them one by one.

Global gitignore [Code Snippet]

Let's learn more about global gitignore, a widely used Git feature that allows files to be ignored within the Git repository.

Global gitignore

A widely used Git feature is to use local .gitignore files which list which names and patterns of files and directories will be ignored within the Git repository.

Learning Git: What Is a Commit?

Learn more about Git commits.

Commits are fundamental to Git, but not all developers have a comprehensive understanding of what a commit actually is and how it gets applied to your project.

In short, a commit is a snapshot of your Git repository at one point in time. In this beginner Git tutorial, we will dig into the journey of creating a commit.

Jenkins CI/CD With Git Secrets

Connect all your Git secrets to the Jenkins pipeline.

It's a common practice to encrypt the secrets/credentials we use in our code and then save it in some secure place. We have a number of options to achieve this, with tools like Vault, Git-crypt, and more. However, git-secret is one simple awesome tool that we can use to store our secrets in our Git repo. Git secret uses gpg for encryption and decryption of secrets. 

Here's how git-secret works. Go to the folder in your repo in which you have files to encrypt. Then, run git init && git secret init. This would initialize your .gitsecret folder. Then you run git secret tell $email , and if you want other users to decrypt the secrets file you have to import their gpg public key and again run git secret tell $otheruseremailid . Now you can run git secret add $secretfilename and git secret hide,which creates $yoursecretfile.secret file, which is an encrypted secret file.

Introduction to React Hooks

React hooks offer us a simplified interface to many React features. This intro will focus on using to access the state and lifecycle of a React component. Hooks are available in React version 16.8.0 or later. To check the version of React your app is running, reference your package.json.

We'll walk through the implementation of React hooks in a simple React app. This app will consume the very developer-friendly Hacker News API and display two views: Top Stories and New Stories. We're going to use two hooks in our app — useState and  useEffect. Hooks are intended to be used in function components; this app will only use function components.

PGP Encryption in Mule 4: How it Works

Expert in the field (10/10 deserves a sugar cube)

Overview

The flow of information that runs through the average business every day is like a river. It’s massive and holds the potential for danger if you’re not careful. Scammers easily lift data from your payment systems if you let them and use it to steal your information. When working with clients, it's very common to receive and send sensitive information, such as server names, usernames, passwords, or even clients' internal information. Sharing this information via an email, text, files, or a 'chat' program is very insecure, unless you encrypt the information using a good encryption method.

Pretty Good Privacy (PGP) is a data encryption and decryption computer program that provides cryptographic privacy and authentication for data communication. PGP is often used for signing, encrypting and decrypting texts, E-mails, files, directories, and whole disk partitions to increase the security of e-mail communications. It was created by Phil Zimmermann in 1991.

Run Faster, Git: The Story of Git Command Slowdown, Branches, and Garbage Collection

Speed up, Git!

My team uses Git for source control. And since we created a bunch of branches for features on the application, we ended up with a ton of branches on our Git repository. While this is not something we cared about initially, the rising number of branches grew rapidly and soon got out of control. This, in turn, resulted in slowing down our Git commands because Git now had to handle the unused branches.

You may also like: Top 20 Git Commands With Examples

This was a challenge that I was interested in solving. In this post, we assess the problems associated with too many Git branches, problem-solving, and a solution to slow Git commands. Let's get started.

Gitting Started With Git

Let Octocat be your guide

In this edition of "Best of DZone," we take a look at all things Git, from basic commands, to theory behind its functionality, to development and deployment patterns. All tutorials and articles featured below are from our wonderful community members who continue to power DZone by sharing their knowledge of and passion for development with readers like you. 

Without further ado, let's git started!

Git Vs. GitHub: Demystifying the Differences

Demystify the difference between Git and GitHub to better serve your source code.

If you have ever worked with code, then you must have come across terms like "Git" and "GitHub." It is also possible that you used them as well. But do you know what exactly is Git or GitHub, and how they are different from each other?

Well, if you don’t, no worries! It’s never too late to learn new stuff, nor is it that tough in this case. By the time you finish this post, you will have a clear understanding of both Git and GitHub and how to best use them.

Using the GitLab REST API to Create a Git Projects

Git some REST with the GitLab REST API.

Git is one of the most popular SCM used currently and GitLab is one of the most popular products used to manage git repositories in a centralized way — not to mention, it comes with lots of handy features.

Instead of using a flat structure, it allows the user to organize repositories into subgroups and use templates to generate repositories and apply security per group to create a group structure. When it comes to projects, we have two options, one is using the WebUI console and the other is using the REST API.

How I Learned to Stop Worrying and Love Git Hooks

The merits of Git as a version control system are difficult to contest, but while Git will do a superb job in keeping track of the commits you and your teammates have made to a repository, it will not, in itself, guarantee the quality of those commits. Git will not stop you from committing code with linting errors in it, nor will it stop you from writing commit messages that convey no information whatsoever about the nature of the commits themselves, and it will, most certainly, not stop you from committing poorly formatted code.

Fortunately, with the help of Git hooks, we can rectify this state of affairs with only a few lines of code. In this tutorial, I will walk you through how to implement Git hooks that will only let you make a commit provided that it meets all the conditions that have been set for what constitutes an acceptable commit. If it does not meet one or more of those conditions, an error message will be shown that contains information about what needs to be done for the commit to pass the checks. In this way, we can keep the commit histories of our code bases neat and tidy, and in doing so make the lives of our teammates, and not to mention our future selves, a great deal easier and more pleasant.

As an added bonus, we will also see to it that code that passes all the tests is formatted before it gets committed. What is not to like about this proposition? Alright, let us get cracking.

Prerequisites

In order to be able to follow this tutorial, you should have a basic grasp of Node.js, npm and Git. If you have never heard of something called package.json and git commit -m [message] sounds like code for something super-duper secret, then I recommend that you pay this and this website a visit before you continue reading.

Our plan of action

First off, we are going to install the dependencies that make implementing pre-commit hooks a walk in the park. Once we have our toolbox, we are going to set up three checks that our commit will have to pass before it is made:

  • The code should be free from linting errors.
  • Any related unit tests should pass.
  • The commit message should adhere to a pre-determined format.

Then, if the commit passes all of the above checks, the code should be formatted before it is committed. An important thing to note is that these checks will only be run on files that have been staged for commit. This is a good thing, because if this were not the case, linting the whole code base and running all the unit tests would add quite an overhead time-wise.

In this tutorial, we will implement the checks discussed above for some front-end boilerplate that uses TypeScript and then Jest for the unit tests and Prettier for the code formatting. The procedure for implementing pre-commit hooks is the same regardless of the stack you are using, so by all means, do not feel compelled to jump on the TypeScript train just because I am riding it; and if you prefer Mocha to Jest, then do your unit tests with Mocha.

Installing the dependencies

First off, we are going to install Husky, which is the package that lets us do whatever checks we see fit before the commit is made. At the root of your project, run:

npm i husky --save-dev

However, as previously discussed, we only want to run the checks on files that have been staged for commit, and for this to be possible, we need to install another package, namely lint-staged:

npm i lint-staged --save-dev

Last, but not least, we are going to install commitlint, which will let us enforce a particular format for our commit messages. I have opted for one of their pre-packaged formats, namely the conventional one, since I think it encourages commit messages that are simple yet to the point. You can read more about it here.

npm install @commitlint/{config-conventional,cli} --save-dev

## If you are on a device that is running windows
npm install @commitlint/config-conventional @commitlint/cli --save-dev

After the commitlint packages have been installed, you need to create a config that tells commitlint to use the conventional format. You can do this from your terminal using the command below:

echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

Great! Now we can move on to the fun part, which is to say implementing our checks!

Implementing our pre-commit hooks

Below is an overview of the scripts that I have in the package.json of my boilerplate project. We are going to run two of these scripts out of the box before a commit is made, namely the lint and prettier scripts. You are probably asking yourself why we will not run the test script as well, since we are going to implement a check that makes sure any related unit tests pass. The answer is that you have to be a little bit more specific with Jest if you do not want all unit tests to run when a commit is made.

"scripts": {
  "start": "webpack-dev-server --config ./webpack.dev.js --mode development",
  "build": "webpack --config ./webpack.prod.js --mode production",
  "test": "jest",
  "lint": "tsc --noEmit",
  "prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
}

As you can tell from the code we added to the package.json file below, creating the pre-commit hooks for the lint and prettier scripts does not get more complicated than telling Husky that before a commit is made, lint-staged needs to be run. Then you tell lint-staged to run the lint and prettier scripts on all staged JavaScript and TypeScript files, and that is it!

"scripts": {
  "start": "webpack-dev-server --config ./webpack.dev.js --mode development",
  "build": "webpack --config ./webpack.prod.js --mode production",
  "test": "jest",
  "lint": "tsc --noEmit",
  "prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
},
"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "./**/*.{ts}": [
    "npm run lint",
    "npm run prettier"
  ]
}

At this point, if you set out to anger the TypeScript compiler by passing a string to a function that expects a number and then try to commit this code, our lint check will stop your commit in its tracks and tell you about the error and where to find it. This way, you can correct the error of your ways, and while I think that, in itself, is pretty powerful, we are not done yet!

By adding "jest --bail --coverage --findRelatedTests" to our configuration for lint-staged, we also make sure that the commit will not be made if any related unit tests do not pass. Coupled with the lint check, this is the code equivalent of wearing two safety harnesses while fixing broken tiles on your roof.

What about making sure that all commit messages adhere to the commitlint conventional format? Commit messages are not files, so we can not handle them with lint-staged, since lint-staged only works its magic on files staged for commit. Instead, we have to return to our configuration for Husky and add another hook, in which case our package.json will look like so:

"scripts": {
  "start": "webpack-dev-server --config ./webpack.dev.js --mode development",
  "build": "webpack --config ./webpack.prod.js --mode production",
  "test": "jest",
  "lint": "tsc --noEmit",
  "prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
},
"husky": {
  "hooks": {
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",  //Our new hook!
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "./**/*.{ts}": [
    "npm run lint",
    "jest --bail --coverage --findRelatedTests", 
    "npm run prettier"
  ]
}

If your commit message does not follow the commitlint conventional format, you will not be able to make your commit: so long, poorly formatted and obscure commit messages!

If you get your house in order and write some code that passes both the linting and unit test checks, and your commit message is properly formatted, lint-staged will run the Prettier script on the files staged for commit before the commit is made, which feels like the icing on the cake. At this point, I think we can feel pretty good about ourselves; a bit smug even.

Implementing pre-commit hooks is not more difficult than that, but the gains of doing so are tremendous. While I am always skeptical of adding yet another step to my workflow, using pre-commit hooks has saved me a world of bother, and I would never go back to making my commits in the dark, if I am allowed to end this tutorial on a somewhat pseudo-poetical note.

The post How I Learned to Stop Worrying and Love Git Hooks appeared first on CSS-Tricks.

Git Pathspecs and How to Use Them

When I was looking through the documentation of git commands, I noticed that many of them had an option for <pathspec>. I initially thought that this was just a technical way to say “path,” and assumed that it could only accept directories and filenames. After diving into the rabbit hole of documentation, I found that the pathspec option of git commands are capable of so much more.

The pathspec is the mechanism that git uses for limiting the scope of a git command to a subset of the repository. If you have used much git, you have likely used a pathspec whether you know it or not. For example, in the command git add README.md, the pathspec is README.md. However, it is capable of much more nuance and flexibility.

So, why should you learn about pathspecs? Since it is a part of many commands, these commands become much more powerful with an understanding of pathspecs. With git add, you can add just the files within a single directory. With git diff, you can examine just the changes made to filenames with an extension of .scss. You can git grep all files except for those in the /dist directory.

In addition, pathspecs can help with the writing of more generic git aliases. For example, I have an alias named git todo, which will search all of my repository files for the string 'todo'. However, I would like for this to show all instances of the string, even if they are not within my current working directory. With pathspecs, we will see how this becomes possible.

File or directory

The most straightforward way to use a pathspec is with just a directory and/or filename. For example, with git add you can do the following. ., src/, and README are the respective pathspecs for each command.

git add .      # add CWD (current working directory)
git add src/   # add src/ directory
git add README # add only README directory

You can also add multiple pathspecs to a command:

git add src/ server/ # adds both src/ and server/ directories

Sometimes, you may see a -- preceding the pathspec of a command. This is used to remove any ambiguity of what is the pathspec and what is part of the command.

Wildcards

In addition to files & directories, you can match patterns using *, ?, and []. The * symbol is used as a wildcard and it will match the / in paths — in other words, it will search through subdirectories.

git log '*.js' # logs all .js files in CWD and subdirectories
git log '.*'   # logs all 'hidden' files and directories in CWD
git log '*/.*' # logs all 'hidden' files and directories in subdirectories

The quotes are important, especially when using *! They prevent your shell (such as bash or ZSH) from attempting to expand the wildcards on their own. For example, let’s take a look at how git ls-files will list files with and without the quotes.

# example directory structure
#
# .
# ├── package-lock.json
# ├── package.json
# └── data
#     ├── bar.json
#     ├── baz.json
#     └── foo.json

git ls-files *.json 

# package-lock.json
# package.json

git ls-files '*.json'

# data/bar.json
# data/baz.json
# data/foo.json
# package-lock.json
# package.json

Since the shell is expanding the * in the first command, git ls-files receives the command as git ls-files package-lock.json package.json. The quotes ensure that git is the one to resolve the wildcard.

You can also use the ? character as a wildcard for a single character. For example, to match either mp3 or mp4 files, you can do the following.

git ls-files '*.mp?'

Bracket expressions

You can also use “bracket expressions” to match a single character out of a set. For example, if you'd like to make matches between either TypeScript or JavaScript files, you can use [tj]. This will match either a t or a j.

git ls-files '*.[tj]s'

This will match either .ts files or .js files. In addition to just using characters, there are certain collections of characters that can be referenced within bracket expressions. For example, you can use [:digit:] within a bracket expression to match any decimal digit, or you can use [:space:] to match any space characters.

git ls-files '*.mp[[:digit:]]' # mp0, mp1, mp2, mp3, ..., mp9
git ls-files '*[[:space:]]*' # matches any path containing a space

To read more about bracket expression and how to use them, check out the GNU manual.

Magic signatures

Pathspecs also have the special tool in their arsenal called “magic signatures” which unlock some additional functionality to your pathspecs. These “magic signatures” are called by using :(signature) at the beginning of your pathspec. If this doesn't make sense, don't worry: some examples will hopefully help clear it up.

top

The top signature tells git to match the pattern from the root of the git repository rather than the current working directory. You can also use the shorthand :/ rather than :(top).

git ls-files ':(top)*.js'
git ls-files ':/*.js' # shorthand

This will list all files in your repository that have an extension of .js. With the top signature this can be called within any subdirectory in your repository. I find this to be especially useful when writing generic git aliases!

git config --global alias.js 'ls-files -- ':(top)*.js''

You can use git js anywhere within your repository to get a list of all JavaScript files in your project using this.

icase

The icase signature tells git to not care about case when matching. This could be useful if you don't care which case the filename is — for example, this could be useful for matching jpg files, which sometimes use the uppercase extension JPG.

git ls-files ':(icase)*.jpg'

literal

The literal signature tells git to treat all of your characters literally. This would be used if you want to treat characters such as * and ? as themselves, rather than as wildcards. Unless your repository has filenames with * or ?, I don't expect that this signature would be used too often.

git log ':(literal)*.js' # returns log for the file '*.js'

glob

When I started learning pathspecs, I noticed that wildcards worked differently than I was used to. Typically I see a single asterisk * as being a wildcard that does not match anything through directories and consecutive asterisks (**) as a “deep” wildcard that does match names through directories. If you would prefer this style of wildcards, you can use the glob magic signature!

This can be useful if you want more fine-grained control over how you search through your project’s directory structure. As an example, take a look at how these two git ls-files can search through a React project.

git ls-files ':(glob)src/components/*/*.jsx' # 'top level' jsx components
git ls-files ':(glob)src/components/**/*.jsx' # 'all' jsx components

attr

Git has the ability to set “attributes” to specific files. You can set these attributes using a .gitattributes file.

# .gitattributes

src/components/vendor/*  vendored # sets 'vendored' attribute
src/styles/vendor/*      vendored

Using the attr magic signature can set attribute requirements for your pathspec. For example, we might want to ignore the above files from a vendor.

git ls-files ':(attr:!vendored)*.js' # searches for non-vendored js files
git ls-files ':(attr:vendored)*.js'  # searches for vendored js files

exclude

Lastly, there is the “exclude'” magic signature (shorthand of :! or :^). This signature works differently from the rest of the magic signatures. After all other pathspecs have been resolved, all pathspecs with an exclude signature are resolved and then removed from the returned paths. For example, you can search through all of your .js files while excluding the .spec.js test files.

git grep 'foo' -- '*.js' ':(exclude)*.spec.js' # search .js files excluding .spec.js
git grep 'foo' -- '*.js' ':!*.spec.js' .       # shorthand for the same

Combining signatures

There is nothing limiting you from using multiple magic signatures in a single pathspec! You can use multiple signatures by separating your magic words with commas within your parenthesis. For example, you can do the following if you’d like to match from the base of your repository (using top), case insensitively (using icase), using only authored code (ignoring vendor files with attr), and using glob-style wildcards (using glob).

git ls-files -- ':(top,icase,glob,attr:!vendored)src/components/*/*.jsx'

The only two magic signatures that you are unable to combine are glob and literal, since they both affect how git deals with wildcards. This is referenced in the git glossary with perhaps my favorite sentence that I have ever read in any documentation.

Glob magic is incompatible with literal magic.


Pathspecs are an integral part of many git commands, but their flexibility is not immediately accessible. By learning how to use wildcards and magic signatures you can multiply your command of the git command line.

The post Git Pathspecs and How to Use Them appeared first on CSS-Tricks.