The most used technology by developers is not Javascript.
It's not Python or HTML.
It hardly even gets mentioned in interviews or listed as a pre...
For further actions, you may consider blocking this person and/or reporting abuse
Just a warning on branches that I've learned the hard way.
You have branch
foo/bar
. Do NOT EVER create a branchfoo
.This may have changed since it's an internal git detail, but in the first case, foo would be a directory. In the second, foo is a file. Something can not be both a file and directory at the same time, so you're asking for a world of hurt.
I would recommend
foo-bar
style naming instead. Tab completion works just as well, and there's no unnecessary directory structure created inrefs
. It also completely avoids this error.EDIT: I found one downside to this. If you like to set all your primary branches to be the default output for
git show-branch
and not show topic branches, you have to use subdirectories for your topic branches. I don't useshow-branch
much at this time, but this could matter to someone who does. Reference: git-scm.com/docs/git-show-branch#_...Interesting, I've never run into this situation but it makes sense. Will keep this in mind.
Slight tweak: replace "Add a name field to the checkout form" with "Add name field to checkout form" --removing the articles saves 15% which can help keep you under the 50-character recommended commit message first-line length.
Very neat summary of git commands! Nice job.
Totally agree that rebase is the most confusing/frustrating thing to learn about git,. But once you practice a bit with on a test repo (I wouldn't dare to do it on a real project 😂) it's a very useful command to work with many branches.
git rerere
to make rebase workflow a little less painful?Though
git rerere
could do with a bit more user facing documentation ;-)Modern git has replacements for the awkwardness of
git checkout
doing two different jobs:git switch
to switch branchesgit restore
to restore a file to its original stateNever
push -f
unless you're the repo manager repairing some terrible mistake that will require everyone to re-clone the repository. I always set my upstream/shared repository to fast-forward pushes only. I call it the "No Jedi Rule" -- force pushing not allowed!Personally I often push force just to keep my commits clean, otherwise have an ugly history like 'bug fix', 'another bug fix', especially when working on new features that require many changes. Also nice to rebase from parent branch to avoid having all the merge commits.
Of course only push force when working alone on your branch.
Oh, definitely, when working alone, I break this rule all the time. It's really just part of the greater rule to never rewrite shared history. You can rewrite your own history all you want, though.
I think
rebase
is under-utilized, too. If I'm working directly on a shared branch, I almost never do apull
. I alwaysfetch
andrebase
to keep the history clean. It actually does more than that, though, it keeps the first parent path consistent, which makes the log much easier to read and the graph much easier to trace. I'm also a fan of usingrebase -i
to squash feature branches into a single commit.I would add
git status
as a really handy command because it tends to teach you about other commands. For example, it will tell you the git rebase abort command when you are part way through a rebaseAdded!
git status
is a pretty beginner level command so I didn't include it at first but you're right that it does much more than we think and it's possibly one of the best learning tools in really internalizing git.Careful now,
git push -f
requires that everyone on the team have as good an understanding ofgit
as you do, particularly when dealing with shared branches likemaster
.We generally don't ever want to see rewriting history on shared branches, because once any other team member grabs the latest (
fetch
/pull
), they're going to have to deal with branches that have diverged. It goes from being a problem for one dev, to being a problem for the whole team.When others are involved, it's a much better practice to resolve the issue as a fast-forward or merge commit, then tack that on to the
HEAD
of the remote branch.Agreed, I will probably add that as a warning. Good suggestion.
git
specific aliases are generally better done asgit
aliases, rather than shell aliases. This way, they only apply when working withgit
, they don't need to be added to your shell rc, and also, if you decide to switch shells, they'll still work.E.g., instead of
Do:
Now, instead of
gbda
, you rungit bda
.There is a couple of typos.
Your last sentence should be:
"Now, instead of gbda, you run git bda"
Thanks! I've corrected it.
I would suggest the following approach to name branches. Assume your team is working on a project with name "Acme Project".
Assign an abbreviation to the project, let say this abbreviation is "ACM".
Then assign tasks in JIRA (or another tracking system) and assign unique number to every task. For example:
ACM-1: Implement "About" dialog.
ACM-2: Fix printing issues.
ACM-291: Refactor "Customer" class and reduce methods complexity and size.
Then assign these tasks to developers.
Upon getting a task, let say ACM-2, a developer creates a local branch with the same name: ACM-2, and works on it. Then it pushes this branch to the remote and makes Pull Request to the master. As the pull request approved and merged, the remote branch ACM-2 is being deleted and the relevant task is being marked as Done.
This approach simplifies communication and task/branch referencing inside of team and I recommend it.
I also follow this kind of branch name and wrote a
prepare-commit-msg
hook for it, which (among other things) places the issue tracker URL in the commit message based on the branch name.gitlab.com/bimlas/home/-/blob/f826...
Yeah agreed that this makes sense if you use Jira. Not everyone uses project management tools like Jira though.
Maybe not Jira but they should be using something!!! Even working alone it's worth using these tools. Kanban, etc. You can do it free with a Gitlab or Azure DevOps account, so why not?
Agreed, i just managed a solo project with gitkraken boards and github issues and i am so glad i did. Kept me on task and eventually was the basis for my generated changelog.
A few things. First, do not use
git branch
for scripting, as it is meant to be user-facing command which output format can change and which is subject to config, butgit for-each-ref
explicitly meant for scripting.Second, instead of
git push --force
, use safer alternative ofgit push --force-with-lease
which would overwrite only your changes.Third,
git restore
might be easier to use thangit reset
.Hey Gabriel, nice article!
I would add another command in order to have a less destructive force push:
git push --force-with-lease
(orggfl
when using oh my zsh).This works like a
git push --force
, but will not override the upstream branch if there's some modification. I usually default to this command when pushing my rebased branches.Here's an article with a good explanation about that: blog.developer.atlassian.com/force...
Nice article, but IMHO not deep enough. I used git command line for a long time, but then moved to visual tools.
Currently I use an awesome visual client: Fork. It really simplifies my work with git.
In the past I used GitKraken which is similar to Fork, but has more features.
Fork looks cool, will try that out. Currently using Gitkraken and built in JetBrains tools but I like the way this looks. I used to use command line too but when you have 20 plus repos it's so much easier to treat these like projects inside a GUI. Thanks for mentioning this. Edit: Dang no Linux client... I need all platforms.
For Windows there is atlassian sourcetree.
BTW many IDE have git plugins or capabilities to easy your work.
I agree, thanks for mentioning. I used Atlassian SourceTree before, but IMHO it is not such intuitive as Fork or GitKraken.
Regarding IDEs, I sometimes use the integration of WebStorm and InelliJ Idea, but still prefer the tools I mentioned.
The
git diff
with the two dots end pointsA..B
should be deprecated as it doesn't actually follow the normal revision range method of being the range of revisions between^A B
.Rather its just
git diff A B
, notgit diff $(git merge-base A B) B
which the two dot notation would normally implyHi Gabriel,
I thought you might find this an interesting read.
The Git Parable
Here is another resource I find helpful Git Explorer
Best regards
Nice article!
Just a little thing:
Wouldn't "unstaged" mean "uncommitted"? Because actually
git reset --hard HEAD
will reset everything to match the latest commit, including the staged changes. Only thing that won't be discarded is untracked files.Hi! thanks really useful!
My two cents: in
.gitattributes
, instead of usingpackage-lock.json binary
You can use
package-lock.json -diff
It will have the same result I guess, preventing git to show the differences ;)
(maybe is more correct with -diff according to the nature of the file)
In CI/CD world, I think
git worktree
is the most instrument.epsi-rns.gitlab.io/devops/2020/02/...
For a visual representation of things, and sometimes easier than having to remember commands, use something like GitKraken. I love that thing, but I also do use the command line ... sometimes. Could make a difference whether you develop for work or as a hobby.
Sometimes if I want to move some work from one location to another without creating a remote branch I diff into a file and then apply the file on the other end,
git diff > /var/tmp/foo.diff
rsync -av /var/tmp/foo.diff remote:/var/tmp
ssh remote
git apply /var/tmp/foo.diff
Thanks. I was hoping for more detail on commit messages. Google has a standard that is multi-line, and I've been wondering how (or if there's a convenient CLI tool) to do that on the command line using a template.
@kevin - you might be interested in Conventional Commit coupled with tools like Git Hooks, Commitzen or Husky.
I wrote about it here stephencharlesweiss.com/blog/2020-...
Very helpful for beginners.
Great summary, I use almost everything of it every day.
git add --patch
is one of my favourites. It adds files by showing exactlly what changed. In OMZ, you can usegapa
does the same thingYou mentioned that you can see the
diff
's of all--staged
changes and see thediff
's of all unstaged changes, but you didn't mention how to show thediff
's of all changes?Thanks for this, really useful, I've used git for years - but always a "little nervously" lol. This will help me think about clearing up some of the clutter.
Yeah getting past the "nervous" stage takes a lot of time, I know exactly what you mean.
It will make you so much more confident in what you can do with a shared codebase and really changes the way you think about your code though.
Great summary. Marked.
tig very handy tool on top of git. I like to use tig for viewing all branch history instead of git log. And I use zsh that gives all the git command aliases built in.
I'll have to check out tig, thanks for the recommendation.
@g_abud I'd highly suggest mentioning
--force-with-lease
instead of-f
when doing force pushes, as it'll save anyone learning from this a mountain of mistakes.Nicely done! I tend to use WebStorms git tools a lot so it's good to refresh my memory on native commands.
Hi Gabriel
Could you please tell me what is the software that in this picture
Gitkraken - fork - source tree - github desktop ?
Great. Thanks for sharing !!
It's look dangerous for beginners.
great
Really cool! Thank You Gabriel!!
Just a question. Is there a way to automatically commit changes from local workstation to GitHub remote repository at a given schedule to save developer's work?
thanks for this Man, very well descriptive for a starter.