Repository: getnikola/nikola

Issue:
github_deploy shouldn’t fail if it can’t determine the source commit
[github_deploy](https://github.com/getnikola/nikola/blob/34e4767194c72c473ff4a31b9a8738f8cc6d662e/nikola/plugins/command/github_deploy.py#L128) tries to deploy from the branch specified by `GITHUB_SOURCE_BRANCH`, which [defaults](https://github.com/getnikola/nikola/blob/34e4767194c72c473ff4a31b9a8738f8cc6d662e/nikola/nikola.py#L620) to `master`. 

This doesn't make sense to me. The default behavior that I would expect would be to just deploy the current contents of the repo. 


Discussion:
`github_deploy` requires a special branching model. There are two branches, one for page source, and another for the page itself. By default, Nikola automatically commits to the source branch for you, so you can keep your site data in sync between different machines. If you don’t want this, just set `GITHUB_COMMIT_SOURCE` to False — but then you need to remember to do your own committing and take care of branches yourself.
This should at least be documented. `nikola github_deploy --help` says nothing about this. 
I also really think that the default should be False for that variable. I don't really understand that use-case. To me, the purpose of `github_deploy` is to add the built pages to the `gh-pages` branch and push it up, nothing more. 
OK, I tried setting that (is [this](https://github.com/asmeurer/blog/commit/671a86bd131578910a821c6c772746bae9d6b5b3) correct?), but I still get this, indicating it is trying to do stuff with the "source" branch.

```
nikola github_deploy
[2017-06-18T22:45:39Z] WARNING: Nikola: The COMMENTS_IN_STORIES option is deprecated, use COMMENTS_IN_PAGES instead.
[2017-06-18T22:45:41Z] WARNING: Nikola: The COMMENTS_IN_STORIES option is deprecated, use COMMENTS_IN_PAGES instead.
fatal: ambiguous argument 'master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Scanning posts............done!
.  render_posts:timeline_changes
Scanning posts............done!
Traceback (most recent call last):
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/doit/doit_cmd.py", line 167, in run
    return command.parse_execute(args)
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/doit/cmd_base.py", line 120, in parse_execute
    return self.execute(params, args)
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/nikola/plugin_categories.py", line 134, in execute
    return self._execute(options, args)
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/nikola/plugins/command/github_deploy.py", line 108, in _execute
    self._commit_and_push(options['commit_message'])
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/nikola/plugins/command/github_deploy.py", line 150, in _commit_and_push
    source_commit = uni_check_output(['git', 'rev-parse', source])
  File "/home/travis/virtualenv/python3.6.1/lib/python3.6/site-packages/nikola/plugins/command/github_deploy.py", line 43, in uni_check_output
    o = subprocess.check_output(*args, **kwargs)
  File "/opt/python/3.6.1/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/opt/python/3.6.1/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['git', 'rev-parse', 'master']' returned non-zero exit status 128.
Note: checking out '671a86bd131578910a821c6c772746bae9d6b5b3'.
```

The context here is that I am trying to get my blog to deploy to gh-pages from Travis CI, which doesn't have `master` in this case because it's a different branch name that I'm building from.
This is documented in the manual: https://getnikola.com/handbook.html#deployment

> GITHUB_COMMIT_SOURCE controls whether or not the source branch is automatically committed to and pushed. We recommend setting it to True, unless you are automating builds with Travis CI.

And we have a guide for Travis as well: https://getnikola.com/blog/automating-nikola-rebuilds-with-travis-ci.html
Well I did set GITHUB_COMMIT_SOURCE to False, and it still wants to commit use the source. So either the docs are wrong or there is a bug. I would prefer the latter interpretation because I would really like the command to be modified so that it doesn't use git for anything other than the gh-pages branch. 

And being documented in the manual is a lot less helpful than being documented in the command help. One is easy to find and the other is only found after a core developer points it out to you. 
Regarding the manual vs command line: documenting software is hard. We expect users to read the manual as well if they want to know more. The manual is also a place where we can describe everything in prose, not tied to config variables or commands.

Could you please show output from a session where `GITHUB_COMMIT_SOURCE = False` doesn’t work? What commands are displayed?
> Regarding the manual vs command line: documenting software is hard. We expect users to read the manual as well if they want to know more. The manual is also a place where we can describe everything in prose, not tied to config variables or commands.

Well you could at least link to the manual from the command line. 

> Could you please show output from a session where GITHUB_COMMIT_SOURCE = False doesn’t work? What commands are displayed?

See https://github.com/getnikola/nikola/issues/2847#issuecomment-309311127
Ah, I see. This isn’t creating a new commit, it merely tries to grab the commit hash for the source commit. This should work if you’re running on the source (master) branch, because that’s the branch that’s just been cloned. Travis should be disabled for the deploy (gh-pages) branch.
That was the Travis "push" build. It also ran in the Travis "PR" build, which apparently does have a `master`, and it tried to run it from master (I know because it failed there, because of a fix I did in my branch for the newest version of Nikola). So the flag doesn't do at all what it says it does. 
Yes, it does. With the option enabled, the thing creates a commit with `git commit` et al [(lines 133-147)](https://github.com/getnikola/nikola/blob/34e4767194c72c473ff4a31b9a8738f8cc6d662e/nikola/plugins/command/github_deploy.py#L133-L147). But regardless of that setting, we use `rev-parse` to get the latest commit hash to use in the commit message. Your scenario and usage is kinda unusual (using different branches and some third-party tool). Since that source check is not important, we could make failure non-fatal.

Resolving patch:
diff --git a/nikola/plugins/command/github_deploy.py b/nikola/plugins/command/github_deploy.py
--- a/nikola/plugins/command/github_deploy.py
+++ b/nikola/plugins/command/github_deploy.py
@@ -146,7 +146,14 @@ def _commit_and_push(self, commit_first_line):
                 else:
                     self.logger.notice('Nothing to commit to source branch.')
 
-            source_commit = uni_check_output(['git', 'rev-parse', source])
+            try:
+                source_commit = uni_check_output(['git', 'rev-parse', source])
+            except subprocess.CalledProcessError:
+                try:
+                    source_commit = uni_check_output(['git', 'rev-parse', 'HEAD'])
+                except subprocess.CalledProcessError:
+                    source_commit = '?'
+
             commit_message = (
                 '{0}\n\n'
                 'Source commit: {1}'


Test patch: