Check out the slide presentation below to learn more about practical use-cases of Git.
You may also like: Top 20 Git Commands With Examples
Tips, Expertise, Articles and Advice from the Pro's for Your Website or Blog to Succeed
Check out the slide presentation below to learn more about practical use-cases of Git.
You may also like: Top 20 Git Commands With Examples
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:
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?
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.
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.
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.
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.
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.
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.
The basic step when committing to open source projects is to fork the project. Then the process is easy you create your branch and you make a pull request. However, from time to time, you need to adjust your branch based on the latest changes.
You may also like: Top 20 Git Commands With Examples
This is how you sync your fork to the original one.
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.
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!
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.
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.
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.
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.
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:
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.
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!
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 plays a significant role in the daily workflow of many developers. Learning to leverage Git can greatly improve the quality and efficiency of your contributions. Here are a few commands to take your Git game to the next level.
You may also like: Top 20 Git Commands With Examples
1. git checkout -
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.
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.
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?'
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.
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.
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.
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'
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'
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
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
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
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.