- Teacher: Jordan McCullough
- Assistant: Matthew McCullough
- Training homepage: http://training.github.com
- Training Twitter handle: @githubtraining (Tweet us if you liked the class!)
- Training/GitHub Educational Videos: http://youtube.com/githubguides
- Facebook page: http://facebook.com/github
- Technical support: https://github.com/contact
- ProGit Book: http://git-scm.com/book
- Desktop Clients: http://mac.github.com, http://windows.github.com
- Platform independent client apps, command line: http://git-scm.com/
- GitHub account signup: https://github.com/signup/free
Q: I am new to Git and i recently automated a daily merge activity. Post this activity, an incident occurred: i was told that the source and destination branch were reversed i.e., merge happened in reverse order. I checked the log but the script looks fine. Moreover, since this script has been running for last few days without any issue, i suspect someone messed up and now trying to cover up things :D Since FBI is busy in other cases, i have decided to investigate this issue myself. This is the command i use for merging: “git merge --no-ff $SOURCE_BRANCH” I need your expert opinion on how can i investigate this matter. I saw but i couldn’t find any verbose option.
A: The git log --format=raw
command provides a raw look at commit history, showing every commit’s parents. In the case of a merge commit, there are two parents. The first listed parent is the destination branch and the second listed parent is the incoming branch. You could use this information to verify that the correct topic branch was merged into the correct destination branch.
commit d98c916e8f02c01764831c12553f21de12624892 tree 5e5953867a1f038da8bd525c55b1f2d888e0841f parent 1aeb10a14d5ecf5a10a4536b873c9feb244a7848 parent ac930287ff16823531b541a8e6a7436279e612be author Junio C Hamano [email protected] 1389990099 -0800 committer Junio C Hamano [email protected] 1389990099 -0800
Merge branch 'maint'
* maint:
git-svn: workaround for a bug in svn serf backend
Q: How do you integrate GitHub issues into the workflow to link code changes with issues?
A: GitHub Issues can link to the SHAs of commits (just mention 5 or more of the first characters of the SHA in the Issue) and commits can link to Issues with a specialized syntax of #ISSUENUMBER and even have behavior when you use “Fixes #ISSUENUM”.
https://help.github.com/articles/closing-issues-via-commit-messages
Q: What is a good plan/way of introducing Git to an existing company without scaring the management?
A: If you are using Subversion, you can “switch to GitHub” as a new hosting platform, but without changing anyone’s workflow. GitHub natively supports Subversion checkouts of all repositories. It matches up the branches, tags, and trunk.
https://github.com/blog/1178-collaborating-on-github-with-subversion
If using just Git, you can use the git svn clone
command to locally start using Git as the front end to a Subversion backend.
http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git
I see those as two places to get started almost subversively, not rocking the boat, but getting use to a more modern platform. This lets a lot of tools continue to work as-is if they were Subversion-centric.
If we’re talking folks who prefer not to use the command line, using the GitHub Web Flow is a way to change, rename, add, delete and change code, even on branches, entirely in the web browser.
https://github.com/blog/1557-github-flow-in-the-browser
Lastly, if colleagues need a more gentle UI to working with Git, desktop clients like http://mac.github.com and http://windows.github.com are very easy-on-the-eyes interfaces to any Git repository (including ones on your local disk).
Q: I sometimes do a git mistake and things become messy and digg myself further down the git mess and I haven’t found a good flow of getting myself out of this rabbit hole and usually ends up asking a colleague for help when this happen. Is there some good steps to think of to get out of a git mess. I noticed that git reflog seems quite useful for this but if you can give me some hints would be great.
A: I like to think of this in a few steps and flavors.
-
Where do I want to go back to? If an earlier point in time is “When it worked” and all I need to do is to get back to that point, I do a
git reset --soft <OLDHASH>
and then commit that with a “Rolled back to an old working point” type of commit message. That’s a pretty broad brush, but is simple. -
If I need to surgically revert what happened in just one older commit (e.g. I wish I hadn’t done that thing 6 commits ago), I
git revert <OLDHASH>
and then review what it did, test the build, and call it good. You can add--no-commit
if you want it to pause before committing.
Q: When reseting i tried using relative pointer to point at the commit i wanted to revert to for example git revert HEAD@{3}
I’ve also seen something similar but with a ~ what is the difference here?
A: Relative pointers are fine, but they’ve bit me far more often than I want to admit. If I did one more commit, HEAD@{3} then isn’t what I thought it was. I like to review with git log --oneline
to see the recent history. Then I use the 7 character hash, which won’t “change” on me like a relative one will for all reverts and resets. The relative approach you are mentioning is fine, but trips me up because it is 0-based from the current HEAD commit. Any action I take could change what {3} points to.
Q: What is the main difference between soft and hard reset? Many times I find the soft one not working and doing it hard but it is more aggressive.
Q: When --soft or --hard is omitted what type of reset occurs?
A: Mixed. It affects the working directory. Soft only affects staging area. Hard affects working directory and staging area.
See Scott’s blog post about reset for even more details: http://git-scm.com/blog/2011/07/11/reset.html
Q: reset and revert are used in the above questions almost interchangeably. What is the difference?
A: Reset hard is used to destructively remove past commits. This is generally used against unpushed code. A: Reset soft is used to return to an older place in time in code, but with an additive commit to the end of the commit graph that can “apologize” for the mistake and shows the “restoration” of the old flavor of code. A: Revert is typically used to surgically revert one commit, leaving intact everything that came after that.
See also: http://git-scm.com/blog/2011/07/11/reset.html
Q: How can you use API creds and secrets with git without letting the world know them?
A: I think the Config answer below addresses most of that. The other pattern is to read creds and secrets from a DB and keep them only in memory, locking what can read them by as many facets as possible (IP lockdown, user lockdown, host name, at-boot-time-typed-master-password). In short, trying at all costs to not have secrets in committed files, but just a placeholder and then read in the real value from centralized and transient sources like environment variables (our favorite pattern). We can seed the environment variable values with a Jenkins plugin that operates on env vars.
Q: Could you please recommend some good practices that are dealing with configuration files like web.config or app.config?
A: At GitHub, we do this in a couple of ways. The dominating pattern is to have the config checked in, but to have the values read from environment variables at runtime. This allows us to keep and secret credentials as transient and not visible to all.
Q: Thanks. What about using different connection strings by different users? Something like a local copy that does not get pushed but gets updates?
A: Correct. We have a .gitignore-ed file that contains the developer’s specific settings. Sometimes, if we are just looking for seed data, we’ll check in that file and have a conditional in the build process that slurps up a “developer.env.vars.sh” that are checked in (no big risk for test username, test, password, sample data). We use a fair bit of env vars like “MODE” that have values like DEV, TEST, PROD that control behavior of both build and execution.
Q: I want to know what the convention is for certain workflow? It seems that that’s something that should be in the docs on GitHub pages but I can’t seem to find it. For example, when you’re collaborating with someone on a project and you have a branch, do you keep your master synced or wait until you’re ready to merge? Let say you run git pull on the branch, does that only sync the branch or does it also sync the master? Once you’re done with the branch and I send a PR to the admin and he/she approves and merges the branch, then deletes it. What’s the procedure for me after that? Do I merge my branch locally and then manually delete the branch or do I just checkout the master branch, git pull and then manually delete the branch?
A: At the top level, you’re (wonderfully) just describing the GitHub Flow.
http://scottchacon.com/2011/08/31/github-flow.html
More specifically, we merge master back into feature branches locally to ensure “we are up to date” and then run one more build. Our CI system also does this automatically. A Pull Request, when wired into Continuous Integration like Jenkins, Travis, CircleCI, TeamCity, etc. all have the ability to test the branch AND also run a build on the branch “predictively” merged into master. Then, you’re basically looking into the “what if I merged this.”
The GitHub Commit Status API is what enables CI to talk to the branches and store results.
https://github.com/blog/1227-commit-status-api
Q: Hi, I was asking from a local vs github perspective. I usually work on my local first and then get github to reflect the local. Once the admin on github merges, I need to know how to then get my local to reflect the github. Your answer didn’t really address that.
A: Ah! Happy to answer that too. All pull requests are associated to a branch. To get that pulled down locally, the pull request says what the Pull Request owner merged to (usually master), so if that’s the case, just git checkout master
and then git pull
which fetches and merges the merged changes in to your working copy of master. If the Pull Request was to be merged to another branch, again, just a git fetch
to get all the upstream commits and branches, then git checkout <branchname>
(the destination of the Pull Request) and then git pull
to merge all the inbound changes to that local working copy of the branch.
We can offer a demo of this, live in the office hours too.
Q: Yes please do a quick run through with a local git. I guess it keeps the branch intact instead of deleting it even though github deleted it?
A: Yes. You’d have to git fetch -p
to prune away the branches deleted upstream.
Q: Just now, Jordan is talking about comparing the base with the branch. Does it matter which comes first? That is, may I use branch first and then base?
A: The order does matter, but just visually. Think of left as “from” and the right as “to”. Or “before” and “after”. Therefore, if you reversed the order, it might look (just visually) like you “deleted” code when truly the intent and action was to add it.
Q: In a Centralized Workflow (Private projects), is it recommended to use git pull with rebase or just pull with merge commits? What are the implications of each option?
A: Open source projects like the SpringSource portfolio like their commits to be rebased to provide very linear history since there are many contributors, but many may be transient. In short, optimizing for future readers of the code. Projects like GitHub.com (we dogfood everything we build) don’t tend to rebase hardly ever. It is optimized for forward velocity, even though everyone is skilled enough to rebase if they wanted to. They just merge to master and continue. The history is a bit cruft-ier but we’ve got good speed.
http://spring.io/blog/2010/12/21/git-and-social-coding-how-to-merge-without-fear http://scottchacon.com/2011/08/31/github-flow.html
Q: How did you know the characters for markdown? (e.g. # = h1)
A: We’ve got a great tutorial on Markdown: http://guides.github.com/overviews/mastering-markdown/
Q: What Language is GitHub written in?
A: Ruby, some Perl, some Python, some Clojure, some Haskell, some C, some Java, and some Go. Loosely coupled services, where at all possible, talking over HTTP and the like. http://www.quora.com/What-programming-language-is-GitHub-written-in
Q: How many languages does Git Support?
A: Everything supported by Pygments http://pygments.org/projects/
Q: on the example where we’re all submitting pull requests and jordan updated his master, do those changes get pushed to our branched copies as well?
A: Forks don’t automatically get the upstream changes, but can have them incorporated with a receipe of commands:
https://help.github.com/articles/syncing-a-fork
Q: Is there a way to get the changed files in teacher's account using GUI in github.com? I do not know any git language.
A: Not possible using just the GitHub GUI, but is possible with the command line. Jordan is demoing this right now in office hours. The above linked article says how to do this as well.
Q: Is it possible to change the name of an existing branch?
A: Yes, but keep the consequences in mind. If others have pulled it, your rename does not propogate to their machine. Best to have a good name before it gets pushed from your machine. Locally, you can git branch -M oldname newname
Q: Once I submit a pull-request on a branch I created, can I continue to make changes to my branch?
A: All changes to a branch that is participating in a pull request “keeps accepting” commits until the pull request is merged or closed. So, briefly, yes. It’s a great way to iterate on code with colleagues and to see how you arrived at the current state.
Q: You seem to be using the web UI and App a lot to interface with your local git. Is that the new conventions now as I was told most shops still use command line to interface with github?
A: GUIs have come a long way in the last two years. A huge percentage of GitHub users now use our GUIs when they use Git, even on repositories that aren’t hosted on GitHub (yup, we made it work with ones that aren’t even hosted with us!).
The most “fancy” GUIs include SmartGit, Git Tower, and SourceTree, but they aim to expose almost all Git options. The more gentle Git GUIs include GitHub for Windows, GitHub for Mac, and GitBox.
Q: Someone recommended the Gitbox app instead of the GitHub for Windows/Mac app. What’s your take?
A: See above. I think it depends on your use case and persona. If you are a power user, SmartGit, GitBox, SourceTree, Git Tower. If more pedestrian using, GitHub for Mac, or GitHub for Windows.
Q: When you have a conflict, what and how do you setup a editor to make changes?
A: I love Araxis, BeyondCompare, P4Merge, and KDiff. These are configured through git config
entries for difftool and mergetool.
http://git-scm.com/docs/git-difftool.html
Q. Will the GitHub for Windows app honor the githooks?
A: I don’t believe hooks are honored in GHfW, possibly partially because GHfW uses libgit2, which isn’t the same lifecycle and code path as invoking, say, git commit
, from the command line. I asked the GHfW developers to doubly confirm my statement and will report back if I need to make any clarifying remarks.
Q: Can you please go over what Rebase is, and perform one for us? Or tell us why the dogma preaches not to do it? I’ve read several different online articles that basically teach rebase, but not to use it. Why not? What does rebase do? Why shouldn’t we use it?
A: Some of our Training team and some other Git-focused resources offer some great explanations of rebasing.
- http://training.github.com/materials/slides/github-foundations.html#/14
- http://git-scm.com/book/en/Git-Branching-Rebasing
- https://www.atlassian.com/git/tutorial/rewriting-git-history#!rebase
Q: How would we include git repos inside other repos? Is it called a git submodule or something? I’ve seen this done before in open source projects, but we’re really paranoid about doing this in our own. We have had several situations where it would be nice though.
A: The idea of nesting Git repos is indeed call Git Submodules. It can be extremely helpful for composing or reusing code. A common example from the Objective-C community is nesting iOS open source “plugins” or “add ons” inside a main project, thus being able to easily consume any updates to code that the plugin publishes over time.
- http://git-scm.com/book/en/Git-Tools-Submodules
- http://www.youtube.com/watch?v=b9IJjxDZXcg
- http://joncairns.com/2011/10/how-to-use-git-submodules/
Q: In CakePHP we have a continuing problem that keeps detecting a file as changed (and I think it’s because it’s unicode multibyte - as the file is a language for asian character set I’m pretty sure), but no matter if this file is changed or not, git detects the file as changed even though we haven’t touched it. We can just add this to .gitignore but I’d like to know WHY this keeps happening. We do not edit the file yet it’s detected as changed.
A: Very likely a change to line endings. You can git diff --raw <FILENAME>
to see what it thinks is changed. Ignoring it could be a good tactic.
Q: When you reviewing others pull request, sometime you need to do some test, except for just reading the code. How can we do that?
Community Answer: A good developer would likely have ran their set of tests before submitting the request. Alternatively you can probably check out their changes to the reviewers machine and run the tests there too.
A: We love to see the integration between a continuous integration system and Pull Requests. For example, you can see some screenshots of how this works in the commit status API blog post. This works with Jenkins, Travis CI, CircleCI, TeamCity and many others. The result of the tests being automatically run are reported back to the branch in the form of a link and an icon.
https://github.com/blog/1227-commit-status-api
Q: We just did a pull request. When I see that this pull request contains some errors/mistakes. Is there a way to revoke my pull request? (If the pull request hasn’t already been merged)?
A: If the pull request remains open, and you do not wish to consider/accept it, you can simply click the “Close” button and a comment on the reason. The Pull Request commits will remain only on the Forked Repository and not impede the main project Repository.
Q: My team has been struggling with LF vs CRLF line endings which make an entire file appear to be different in the pull request. Any tips for normalizing line endings across operating systems?
Community Answer: Most editors should have config for changing line endings. As long as each developer sets up their editor to obey one it should work out ok. Comparison tools can also be told to ignore whitespace.
A: See also the Help article on line endings at https://help.github.com/articles/dealing-with-line-endings
My suggestion is to aim for LF in the central repository. This is done with input
as the setting on Linux and Mac machines and auto
on Windows machines. This has helped us significantly on a lot of open source projects. I’ll also often try to help normalize the repo with one big commit, doing a dos2unix
and then adding and committing with an appropriate commit message.
Q: How did you add an image (of the Octocat with an apple) to your repo? It seems (on GitHub.com at least) that I can only add text-based files (clicking the plus-document icon to the right of the repo name).
A: File additions other than text are via the GitHub GUIs and desktop clients like command line only at the moment. I have to admit I’d too would love file uploads on the web!