Hi, I'm Jason McCreary. I go by JMac.
I'm a full stack and iOS developer who likes building products and services. Recently this includes services like Laravel Shift and Getting Git.
I've been programming for 20 years. I'm very passionate about what I do and lately I've been on a mission to empower developers to master Git. So I'm glad to answer any and all of your Git questions (or anything else).
My AMA will start at 2PM ET today, September 13th, so please feel free to Ask Me Anything!
Latest comments (102)
Hi. We never used Git in our company. I have good knowledge of Git. I'm using my all open source projects. What should I do to teach it, my teammates?
They don't accept work with Git o related technologies. I just work with Git. What should I do to convince them?
I suggest showing them how quickly Git and Git services can do things - creating and switching branches, sharing work, enhancing the code review process with Pull Requests, etc.
What is your reccomended method for merging a feature branch into master?
Depends.
If working on a team, I recommend doing so through a Pull Request. This provides a formal merge process which serves not only as record, but also an opportunity for code review and discussion.
If it's just you, I recommend merging from the command line:
git merge the-feature-branch
I regularly use the basics: pull, add, commit, push, and merge. What should I learn next?
Sounds like you have the basics. Where are you experiencing a bottleneck?
No bottleneck, but I know that there is a lot more to git. What should I learn next?
I'm command line all the way, so I couldn't say. In general, if you've found a tool that works for you - use it.
Have the club split the cost of the Getting Git video series and watch them together in your next meeting.
What do you think of these git-tips?
Pretty awesome. Thanks for sharing.
If I do a "git clone," I get the master version clone of the entire supermodule/submodule repository. If I subsequently do "git submodule update --init," my submodules are set to dangling HEADs (no branch), corresponding to the versions when the supermodule was (last?) set up.
I'd like to change the "update --init" to point to the (new) master versions of the submodules. Not sure what's the right commands/sequences to do this.
Please help.
What is the best way to clean up old commits? E.g. I only want to keep history of the last 2 years and remove all older commits, in fact treating the 2 year old version as the initial commit?
Related: how to remove commits of a bigger file that was pushed in by a developer and that needs to be moved out (e.g. to git LFS or just a file repository server).
How can I assign a GitHub user to a specific .git repo, and not global? I need to have different users for different repos in the same laptop
If I understand correctly, you use different GitHub users for different repos on the same machine.
The way Git configuration works is it will look for local config, then roll up to global config. So, you can set the author info for each local repo by running:
(note the missing
--global
)I have my Develop branch then I created a feature/nav-bar branch, my code needs to be rebased because there are new changes in Develop branch, how do I do that... so let's say I am in my feature/nav-bar branch in that "folder" should I run "git rebase develop" ?
Yes. From the feature branch, you would run
git rebase develop
to fast forward your branch with the latest change and replay your work. Check out my previous post for a closer look at git rebase.You don't have to be in any folder, just the repo.
Scenario: you work with 4 other developers on a project, where you use the Git Flow methods (though no pull-requests).
When will you use `
git rebase
and when will you use
git merge --no-ff
`?I'd add to Jason's answer that
git rebase
is far more than an alternative workflow to merge. I use it heavily during local development for example, before and during merge/pull requests:Updating your in-progress branch to include changes someone else has merged that you need (this is the classic example)
Moving your work to be based on a different branch (eg. you originally branched from
master
as a hotfix, but part-way through you've found it makes more sense to fix with the changes already ondevelop
to avoid additional changes when merging).Separating commits from a branch into multiple branches that make more sense for review. I often do this if I find a bug while writing a tests for existing code - commit a fix on the tests branch, then move the fix commit(s) to a separate branch once everything is done to submit them separately to the test changes. You can also do this with other people's commits and the authorship is not modified.
Changing the order of commits, dropping, squashing and combining commits (ie. fixup)
Amending a commit on my local branch that's not the last commit (rewording, adding/removing changes, etc).
git rebase
is likely reserved for feature branches to prepare them for merge. Under Git Flow, you'd likely never want to rungit rebase
on the long lived branches.The
git merge --no-ff
ensures the merge does not fast forward your commits onto the target branch. Essentially, this guarantees a merge commit.I sometimes have trouble simply when checking out/resetting to a particular commit.
The perfect example is the git version of the Gentoo portage tree.
If I reset to some very early point in time and then go back to my origin/master, it often complains about newly added or modified files, without me actually touching anything.
Why is that?
reset
doesn't sound like the right command for what you describe. By default,reset
will uncommit the changes and put them in your index. So when you go to switch branches, it's likely complaining since Git sees changes in the index.To go back to a previous point in time,
checkout
is the more appropriate command.If I was to create a new branch and wanted it to be at exactly that commit, would I then use
checkout
for a detached head and then acheckout -b foobar
?Is there any better way to achieve this?
You could do that.
Many forget
checkout
takes second argument as a reference to checkout from. So if your goal was simply to checkout a branch from an older point in time (commitabc123
), you could run:git checkout -b foobar abc123
Why git is one of the technologies to learn ?
It's the modern, popular tool for version control. So assuming your using version control (you should be), you should try it out.
Personally I think Git offers an abysmal interface, conceived by elite engineers that wanted to do versioning their own way, but without any idea of usability. This isn't suprising from the minds that conceived Linux (including Torvalds) and its ecosystem. Just reading the documentation is a free pass to a massive headache for any novice, and this implies its discoverability is also more or less non-existent.
While some concepts and worflow methods have been a long awaited evolution of the ones found in SVN, others have a very weak connection with the main objective of the tool: versioning stuff.
I feel one of the biggest issues with Git is its monolithic nature: you can do a lot of things with Git, but some - from a more modern point of view - are better suited for external plugins. For example,
git rerere
is something a nice middleware could do instead.What can you say to convince me I'm wrong?
Keep in mind that I did read your article about not using GUIs - but it's far from enough, as its main point ("Don't use wizard code you don't understand") does not imply, in my opinion, that you need to understand the underlying Git commands, but just what a GUI command means to your Git workflow. In short, you should know what's a commit, a branch, a merge and so on, but you might not care how to do it with the CLI. (I have a draft of an article about it.)
Nothing. Aside from your viewpoint on the creators of Git, it sounds like we're on the same page.
As a new developer what parts of Git would you recommend mastering first to be productive in a workplace environment and how you go about mastering it?
If you can do all that, you'll be well ahead of most other developers. For reasons, see my previous reply.
Are there any git shortcuts or git bash scripts you'd like to see added (or you could contribute to) github.com/tj/git-extras.
Super useful project and I love using the extra tools there like git delete-branch (Local and remote on github Bitbucket etc) and even mundane stuff like git count.
git-extras is pretty cool.
I don't have many aliases. Only Git command completion. I like typing the full command so I'm explicit about what I'm doing. Too often with Git you can run some shorthand and forget the underlying commands.
Here are all my aliases:
@gonedark / Jason McCreary do you have a response for my previous question about redo'ing the timestamps of old git commits?
What shortcuts do you have similar to github.com/potatolabs/git-redate?
What is the use case for needing to change the date?
Various reasons. Git rebasing and merging skew with the dates, and one wants to make the timestamp of the recent commits to "look" more reasonable.
Anyhow, what I'm really looking for is a shortcut for modify git timestamps without doing the manual work of setting GIT_AUTHOR_DATE and GIT_COMMITER_DATE with stackoverflow.com/a/3896112 .
Any insights @gonedark ?
@jonlai have you ever found a trick to get that alias to work?
My solution under zsh is
used as
example
Speaking of aliases and shortcuts aliases or git extras bash scripts aside.
Do you have a nice good clean shortcut to do git timestamp changes similar to git-redate (github.com/PotatoLabs/git-redate).
I find manually doing the redundant GIT_AUTHOR_DATE and GIT_COMMITTER_DATE changes for just one commit edit tedious (see stackoverflow.com/questions/454734...).
Git extras bash scripts seem to extend beyond aliases -- thanks for sharing your aliases by the way.
I'd like to start developing git bash scripts like git extras, but not on that level there yet.