Wednesday, October 12, 2016

Python in Xcode 7 - Stack Overflow

?? how can run with "Debug executable" on?

Python in Xcode 7 - Stack Overflow


244
down vote
accepted
I figured it out! The steps make it look like it will take more effort than it actually does.

These instructions are for creating a project from scratch. If you have existing Python scripts that you wish to include in this project, you will obviously need to slightly deviate from these instructions.

If you find that these instructions no longer work or are unclear due to changes in Xcode updates, please let me know. I will make the necessary corrections.

Open Xcode. The instructions for either are the same.
In the menu bar, click “File” → “New” → “New Project…”.
Select “Other” in the left pane, then "External Build System" in the right page, and next click "Next".
Enter the product name, organization name, or organization identifier.
For the “Build Tool” field, type in /usr/local/bin/python3 for Python 3 or /usr/bin/python for Python 2 and then click “Next”. Note that this assumes you have the symbolic link (that is setup by default) that resolves to the Python executable. If you are unsure as to where your Python executables are, enter either of these commands into Terminal: which python3 and which python.
Click “Next”.
Choose where to save it and click “Create”.
In the menu bar, click “File” → “New” → “New File…”.
Select “Other” under “OS X”.
Select “Empty” and click “Next”.
Navigate to the project folder (it will not work, otherwise), enter the name of the Python file (including the “.py” extension), and click “Create”.
In the menu bar, click “Product” → “Scheme” → “Edit Scheme…”.
Click “Run” in the left pane.
In the “Info” tab, click the “Executable” field and then click “Other…”.
Navigate to the executable from Step 6. You may need to use ⇧⌘G to type in the directory if it is hidden.
Select the executable and click "Choose".
Uncheck “Debug executable”. If you skip this step, Xcode will try to debug the Python executable itself. I am unaware of a way to integrate an external debugging tool into Xcode.
Click the “+” icon under “Arguments Passed On Launch”. You might have to expand that section by clicking on the triangle pointing to the right.
Type in $(SRCROOT)/ (or $(SOURCE_ROOT)/) and then the name of the Python file you want to test. Remember, the Python program must be in the project folder. Otherwise, you will have to type out the full path (or relative path if it's in a subfolder of the project folder) here. If there are spaces anywhere in the full path, you must include quotation marks at the beginning and end of this.
Click “Close”.
Note that if you open the "Utilities" panel, with the "Show the File inspector" tab active, the file type is automatically set to "Default - Python script". Feel free to look through all the file type options it has, to gain an idea as to what all it is capable of doing. The method above can be applied to any interpreted language. As of right now, I have yet to figure out exactly how to get it to work with Java; then again, I haven't done too much research. Surely there is some documentation floating around on the web about all of this.

Running without administrative privileges:

If you do not have administrative privileges or are not in the Developer group, you can still use Xcode for Python programming (but you still won't be able to develop in languages that require compiling). Instead of using the play button, in the menu bar, click "Product" → "Perform Action" → "Run Without Building" or simply use the keyboard shortcut ^⌘R.

Other Notes:

To change the text encoding, line endings, and/or indentation settings, open the "Utilities" panel and click "Show the File inspector" tab active. There, you will find these settings.

For more information about Xcode's build settings, there is no better source than this. I'd be interested in hearing from somebody who got this to work with unsupported compiled languages. This process should work for any other interpreted language. Just be sure to change Step 6 and Step 16 accordingly.

Wednesday, October 5, 2016

A Celery-like Python Task Queue in 55 Lines of Code

A Celery-like Python Task Queue in 55 Lines of Code: A Celery-like Python Task Queue in 55 Lines of Code



A Celery-like Python Task Queue in 55 Lines of Code

Update: you can check this out on GitHub here.
Celery is probably the best known task queuing Python package around. It makes asynchronous execution of Python code both possible and reasonably straightforward. It does, however, come with a good deal of complexity, and it's not as simple to use as I would like (i.e. for many use cases it's overkill). So I wrote a distributed Python task queue. In 55 lines of code (caveat: using two awesome libraries).

Background

What does a distributed task queue do? It takes code like the following (taken from the documentation forRQ, another Celery alternative):
import requests

def count_words_in_page(url):
    resp = requests.get(url)
    return len(resp.text.split())
and allows it to be sent to a worker process (possibly on another machine) for execution. The worker process then sends back the results after the calculation is complete. In the meantime, the sender doesn't have to block waiting for the (possibly expensive) calculation to complete. They can just periodically check if the results are ready.
So what's the absolute simplest way we could do this? I submit to you, brokest.py:
"""Broker-less distributed task queue."""
import pickle

import zmq
import cloud

HOST = '127.0.0.1'
PORT = 9090
TASK_SOCKET = zmq.Context().socket(zmq.REQ)
TASK_SOCKET.connect('tcp://{}:{}'.format(HOST, PORT))

class Worker(object):
    """A remote task executor."""

    def __init__(self, host=HOST, port=PORT):
        """Initialize worker."""
        self.host = host
        self.port = port
        self._context = zmq.Context()
        self._socket = self._context.socket(zmq.REP)

    def start(self):
        """Start listening for tasks."""
        self._socket.bind('tcp://{}:{}'.format(self.host, self.port))
        while True:
            runnable_string = self._socket.recv_pyobj()
            runnable = pickle.loads(runnable_string)
            self._socket.send_pyobj('')
            args = self._socket.recv_pyobj()
            self._socket.send_pyobj('')
            kwargs = self._socket.recv_pyobj()
            response = self._do_work(runnable, args, kwargs)
            self._socket.send_pyobj(response)

    def _do_work(self, task, args, kwargs):
        """Return the result of executing the given task."""
        print('Running [{}] with args [{}] and kwargs [{}]'.format(
            task, args, kwargs))
        return task(*args, **kwargs)

def queue(runnable, *args, **kwargs):
    """Return the result of running the task *runnable* with the given 
    arguments."""
    runnable_string = cloud.serialization.cloudpickle.dumps(runnable)
    TASK_SOCKET.send_pyobj(runnable_string)
    TASK_SOCKET.recv()
    TASK_SOCKET.send_pyobj(args)
    TASK_SOCKET.recv()
    TASK_SOCKET.send_pyobj(kwargs)
    results = TASK_SOCKET.recv_pyobj()
    return results

if __name__ == '__main__':
    w = Worker()
    w.start()
And to use it? Here's the complete contents of app.py:
import requests
from brokest import queue

def count_words_in_page(url):
    resp = requests.get(url)
    return len(resp.text.split())

result = queue(count_words_in_page, 'http://www.jeffknupp.com')
print result
Rather than calling the function directly, you simply call brokest.queue with the function and it arguments as arguments. While the current implementation is blocking, it would be trivially easy to make it non-blocking. Adding multiple workers is just a matter of adding code to make use of a config file with their locations.
Clearly, the stars here are zmq and cloudZeroMQ makes creating distributed systems a lot easier, and the documentation is chock full of ZeroMQ design patterns (ours is probably the simplest one, Request-Reply).
cloud is the LGPL'd PiCloud library. PiCloud is a company whose value proposition is that they let you seamlessly run computationally intensive Python code using Amazon EC2 for computing resources. Part of making that a reality, though, required a way to pickle functions and their dependencies (functions are not normally directly pickle-able). In our example, the Worker is able to make use of code using requestslibrary despite not having imported it. It's the secret sauce that makes this all possible.

Is This For Real?

The code works, but my intention was not to create a production quality distributed task queue. Rather, it was to show how new libraries are making it easier than ever to create distributed systems. Having a way to pickle code objects and their dependencies is a huge win, and I'm angry I hadn't heard of PiCloud earlier.
One of the best things about being a programmer is the ability to tinker not just with things, but with ideas. I can take existing ideas and tweak them, or combine existing ideas in new ways. I think brokest is an interesting example of how easy it has become to create distributed systems.
Posted on  by 

Discuss Posts With Other Readers at discourse.jeffknupp.com!

Like this article?

Why not sign up for Python Tutoring? Sessions can be held remotely using Google+/Skype or in-person if you're in the NYC area. Email jeff@jeffknupp.com if interested.
Sign up for the free jeffknupp.com email newsletter. Sent roughly once a month, it focuses on Python programming, scalable web development, and growing your freelance consultancy. And of course, you'll never be spammed, your privacy is protected, and you can opt out at any time.

Wednesday, August 17, 2016

A successful Git branching model � nvie.com

A successful Git branching model � nvie.com
A successful Git branching model
By Vincent Driessen
on Tuesday, January 05, 2010

We Provide the Highest Level of Transparency & Control for Cloud
ads via Carbon
In this post I present the development model that I’ve introduced for some of my projects (both at work and private) about a year ago, and which has turned out to be very successful. I’ve been meaning to write about it for a while now, but I’ve never really found the time to do so thoroughly, until now. I won’t talk about any of the projects’ details, merely about the branching strategy and release management.



It focuses around Git as the tool for the versioning of all of our source code. (By the way, if you’re interested in Git, our company GitPrime provides some awesome realtime data analytics on software engineering performance.)

Why git?
For a thorough discussion on the pros and cons of Git compared to centralized source code control systems, see the web. There are plenty of flame wars going on there. As a developer, I prefer Git above all other tools around today. Git really changed the way developers think of merging and branching. From the classic CVS/Subversion world I came from, merging/branching has always been considered a bit scary (“beware of merge conflicts, they bite you!”) and something you only do every once in a while.

But with Git, these actions are extremely cheap and simple, and they are considered one of the core parts of your daily workflow, really. For example, in CVS/Subversion books, branching and merging is first discussed in the later chapters (for advanced users), while in every Git book, it’s already covered in chapter 3 (basics).

As a consequence of its simplicity and repetitive nature, branching and merging are no longer something to be afraid of. Version control tools are supposed to assist in branching/merging more than anything else.

Enough about the tools, let’s head onto the development model. The model that I’m going to present here is essentially no more than a set of procedures that every team member has to follow in order to come to a managed software development process.

Decentralized but centralized
The repository setup that we use and that works well with this branching model, is that with a central “truth” repo. Note that this repo is only considered to be the central one (since Git is a DVCS, there is no such thing as a central repo at a technical level). We will refer to this repo as origin, since this name is familiar to all Git users.



Each developer pulls and pushes to origin. But besides the centralized push-pull relationships, each developer may also pull changes from other peers to form sub teams. For example, this might be useful to work together with two or more developers on a big new feature, before pushing the work in progress to origin prematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.

Technically, this means nothing more than that Alice has defined a Git remote, named bob, pointing to Bob’s repository, and vice versa.

The main branches


At the core, the development model is greatly inspired by existing models out there. The central repo holds two main branches with an infinite lifetime:

master
develop
The master branch at origin should be familiar to every Git user. Parallel to the master branch, another branch exists called develop.

We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state.

We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where any automatic nightly builds are built from.

When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. How this is done in detail will be discussed further on.

Therefore, each time when changes are merged back into master, this is a new production release by definition. We tend to be very strict at this, so that theoretically, we could use a Git hook script to automatically build and roll-out our software to our production servers everytime there was a commit on master.

Supporting branches
Next to the main branches master and develop, our development model uses a variety of supporting branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

The different types of branches we may use are:

Feature branches
Release branches
Hotfix branches
Each of these branches have a specific purpose and are bound to strict rules as to which branches may be their originating branch and which branches must be their merge targets. We will walk through them in a minute.

By no means are these branches “special” from a technical perspective. The branch types are categorized by how we use them. They are of course plain old Git branches.

Feature branches


May branch off from:
develop
Must merge back into:
develop
Branch naming convention:
anything except master, develop, release-*, or hotfix-*
Feature branches (or sometimes called topic branches) are used to develop new features for the upcoming or a distant future release. When starting development of a feature, the target release in which this feature will be incorporated may well be unknown at that point. The essence of a feature branch is that it exists as long as the feature is in development, but will eventually be merged back into develop (to definitely add the new feature to the upcoming release) or discarded (in case of a disappointing experiment).

Feature branches typically exist in developer repos only, not in origin.

Creating a feature branch
When starting work on a new feature, branch off from the develop branch.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
Incorporating a finished feature on develop
Finished features may be merged into the develop branch to definitely add them to the upcoming release:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop
The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:



In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the --no-ff flag was used.

Yes, it will create a few more (empty) commit objects, but the gain is much bigger than the cost.

Release branches
May branch off from:
develop
Must merge back into:
develop and master
Branch naming convention:
release-*
Release branches support preparation of a new production release. They allow for last-minute dotting of i’s and crossing t’s. Furthermore, they allow for minor bug fixes and preparing meta-data for a release (version number, build dates, etc.). By doing all of this work on a release branch, the develop branch is cleared to receive features for the next big release.

The key moment to branch off a new release branch from develop is when develop (almost) reflects the desired state of the new release. At least all features that are targeted for the release-to-be-built must be merged in to develop at this point in time. All features targeted at future releases may not—they must wait until after the release branch is branched off.

It is exactly at the start of a release branch that the upcoming release gets assigned a version number—not any earlier. Up until that moment, the develop branch reflected changes for the “next release”, but it is unclear whether that “next release” will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project’s rules on version number bumping.

Creating a release branch
Release branches are created from the develop branch. For example, say version 1.1.5 is the current production release and we have a big release coming up. The state of develop is ready for the “next release” and we have decided that this will become version 1.2 (rather than 1.1.6 or 2.0). So we branch off and give the release branch a name reflecting the new version number:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)
After creating a new branch and switching to it, we bump the version number. Here, bump-version.sh is a fictional shell script that changes some files in the working copy to reflect the new version. (This can of course be a manual change—the point being that some files change.) Then, the bumped version number is committed.

This new branch may exist there for a while, until the release may be rolled out definitely. During that time, bug fixes may be applied in this branch (rather than on the develop branch). Adding large new features here is strictly prohibited. They must be merged into develop, and therefore, wait for the next big release.

Finishing a release branch
When the state of the release branch is ready to become a real release, some actions need to be carried out. First, the release branch is merged into master (since every commit on master is a new release by definition, remember). Next, that commit on master must be tagged for easy future reference to this historical version. Finally, the changes made on the release branch need to be merged back into develop, so that future releases also contain these bug fixes.

The first two steps in Git:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2
The release is now done, and tagged for future reference.

Edit: You might as well want to use the -s or -u flags to sign your tag cryptographically.

To keep the changes made in the release branch, we need to merge those back into develop, though. In Git:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
This step may well lead to a merge conflict (probably even, since we have changed the version number). If so, fix it and commit.

Now we are really done and the release branch may be removed, since we don’t need it anymore:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).
Hotfix branches


May branch off from:
master
Must merge back into:
develop and master
Branch naming convention:
hotfix-*
Hotfix branches are very much like release branches in that they are also meant to prepare for a new production release, albeit unplanned. They arise from the necessity to act immediately upon an undesired state of a live production version. When a critical bug in a production version must be resolved immediately, a hotfix branch may be branched off from the corresponding tag on the master branch that marks the production version.

The essence is that work of team members (on the develop branch) can continue, while another person is preparing a quick production fix.

Creating the hotfix branch
Hotfix branches are created from the master branch. For example, say version 1.2 is the current production release running live and causing troubles due to a severe bug. But changes on develop are yet unstable. We may then branch off a hotfix branch and start fixing the problem:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)
Don’t forget to bump the version number after branching off!

Then, fix the bug and commit the fix in one or more separate commits.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)
Finishing a hotfix branch

When finished, the bugfix needs to be merged back into master, but also needs to be merged back into develop, in order to safeguard that the bugfix is included in the next release as well. This is completely similar to how release branches are finished.

First, update master and tag the release.

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1
Edit: You might as well want to use the -s or -u flags to sign your tag cryptographically.

Next, include the bugfix in develop, too:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
The one exception to the rule here is that, when a release branch currently exists, the hotfix changes need to be merged into that release branch, instead of develop. Back-merging the bugfix into the release branch will eventually result in the bugfix being merged into develop too, when the release branch is finished. (If work in develop immediately requires this bugfix and cannot wait for the release branch to be finished, you may safely merge the bugfix into develop now already as well.)

Finally, remove the temporary branch:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).
Summary
While there is nothing really shocking new to this branching model, the “big picture” figure that this post began with has turned out to be tremendously useful in our projects. It forms an elegant mental model that is easy to comprehend and allows team members to develop a shared understanding of the branching and releasing processes.

A high-quality PDF version of the figure is provided here. Go ahead and hang it on the wall for quick reference at any time.

Update: And for anyone who requested it: here’s the gitflow-model.src.key of the main diagram image (Apple Keynote).


Git-branching-model.pdf

If you want to get in touch, I'm @nvie on Twitter.

Thursday, July 28, 2016

version control - How to remove/delete a large file from commit history in Git repository? - Stack Overflow

version control - How to remove/delete a large file from commit history in Git repository? - Stack Overflow: active oldest votes
up vote
207
down vote
accepted
Use the BFG Repo-Cleaner, a simpler, faster alternative to git-filter-branch specifically designed for removing unwanted files from Git history.

Carefully follow the usage instructions, the core part is just this:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git
Any files over 100MB in size (that aren't in your latest commit) will be removed from your Git repository's history. You can then use git gc to clean away the dead data:

$ git gc --prune=now --aggressive
The BFG is typically at least 10-50x faster than running git-filter-branch, and generally easier to use.

Full disclosure: I'm the author of the BFG Repo-Cleaner.

Tuesday, May 31, 2016

Mac OS X Reversing Tools | Reverse Engineering Mac OS X

Mac OS X Reversing Tools | Reverse Engineering Mac OS X: Tools
This page will hold local copies of reversing tools and scripts useful for Mac OS X reversing.

gdbinit – enhanced gdb output

0xEd v1.0.7 – hex editor
(SHA1(0xED.tar.bz2)= f64466b2d3cbf7b6d64eccfc1a36f8c0a7e3866d)

HexFiend – another hex editor
(SHA1(HexFiend.dmg)= 690ac9f60ab85ec6430b3db0376d0d20d3cecd9a)

Synalize it v1.0.3 – hex editor with binary file analysis grammar (looks great!!!) – Original website
(SHA256(SynalyzeIt_1.0.3.1.zip)= ab71d0f2e573321946ec144e60594d4155961b42aeafb2f5b5080bf9961348d0)

OTX v0.16b – disassembler
(SHA1(otx.dmg)= ff4987b7f22da6b289ee2bc7daa7c1a3db64ffed)

offset1.3.pl.gz – my offset calculator for fat binaries
(SHA256(offset1.3.pl.gz)= 2b091f2ea5fddce3ca22251b8d81578ba708811d4a3d2fdce8ae0c8a7972f1b3)

ptool1.3.pl.gz – sort of replacement for otool to display mach-o binaries headers
(SHA256(ptool1.3.pl.gz)= 715481e62978c183ccd82311acb6ccced2d12cab76a0c9ffb0345d653bce37ba)

ocalc.c – ghalen’s offset calculator for fat binaries
(SHA1(ocalc.c)= e32da310af2a25a09fc2de9c4826b113ab8ac705)

onyx-the-black-cat.v0.3 – anti anti-debug kernel module
(SHA1(onyx-the-black-cat-v0-3.tgz)= 194c2e7481113b562c6e23a2b5059769bc9e8ffb)

onyx-the-black-cat-v0.4 – version for Snow Leopard (not 64bit compatible, yet!)
(SHA1(onyx-the-black-cat-v0.4.tgz)= 5dff3c4a9246f2886b470aa0ab60b5e237ca3659)

AlanQuatermain-appencryptor – encryptor/decryptor for Apple Encrypted Binaries
SHA1(AlanQuatermain-appencryptor-a3da7c5.tar.gz)= 3c7f70fed359b7e259f08d00001ead936baef041

Tuesday, September 22, 2015

Finding a branch point with Git? - Stack Overflow

I have a repository with branches master and A and lots of merge activity between the two. How can I find the commit in my repository when branch A was created based on master?
My repository basically looks like this:
-- X -- A -- B -- C -- D -- F  (master) 
          \     /   \     /
           \   /     \   /
             G -- H -- I -- J  (branch A)
I'm looking for revision A, which is not what git merge-base (--all) finds.
shareimprove this question
up vote229down voteaccepted
I was looking for the same thing, and I found this question. Thank you for asking it!
However, I found that the answers I see here don't seem to quite give the answer you asked for (or that I was looking for) -- they seem to give the G commit, instead of the A commit.
So, I've created the following tree (letters assigned in chronological order), so I could test things out:
A - B - D - F - G   <- "master" branch (at G)
     \   \     /
      C - E --'     <- "topic" branch (still at E)
This looks a little different than yours, because I wanted to make sure that I got (referring to this graph, not yours) B, but not A (and not D or E). Here are the letters attached to SHA prefixes and commit messages (my repo can be cloned from here, if that's interesting to anyone):
G: a9546a2 merge from topic back to master
F: e7c863d commit on master after master was merged to topic
E: 648ca35 merging master onto topic
D: 37ad159 post-branch commit on master
C: 132ee2a first commit on topic branch
B: 6aafd7f second commit on master before branching
A: 4112403 initial commit on master
So, the goal: find B. Here are three ways that I found, after a bit of tinkering:

1. visually, with gitk:

You should visually see a tree like this (as viewed from master):
gitk screen capture from master
or here (as viewed from topic):
gitk screen capture from topic
in both cases, I've selected the commit that is B in my graph. Once you click on it, its full SHA is presented in a text input field just below the graph.

2. visually, but from the terminal:

git log --graph --oneline --all
which shows (assuming git config --global color.ui auto):
output of git log --graph --oneline --all
Or, in straight text:
*   a9546a2 merge from topic back to master
|\  
| *   648ca35 merging master onto topic
| |\  
| * | 132ee2a first commit on topic branch
* | | e7c863d commit on master after master was merged to topic
| |/  
|/|   
* | 37ad159 post-branch commit on master
|/  
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master
in either case, we see the 6aafd7f commit as the lowest common point, i.e. B in my graph, or Ain yours.

3. With shell magic:

You don't specify in your question whether you wanted something like the above, or a single command that'll just get you the one revision, and nothing else. Well, here's the latter:
diff -u <(git rev-list --first-parent topic) \
             <(git rev-list --first-parent master) | \
     sed -ne 's/^ //p' | head -1
6aafd7ff98017c816033df18395c5c1e7829960d
Which you can also put into your ~/.gitconfig as (note: trailing dash is important; thanks Brian for bringing attention to that):
[alias]
    oldest-ancestor = !zsh -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -
Which could be done via the following (convoluted with quoting) command-line:
git config --global alias.oldest-ancestor '!zsh -c '\''diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne "s/^ //p" | head -1'\'' -'
Note: zsh could just as easily have been bash, but sh will not work -- the <() syntax doesn't exist in vanilla sh. (Thank you again, @conny, for making me aware of it in a comment on another answer on this page!)

Note: Alternate version of the above:

Thanks to liori for pointing out that the above could fall down when comparing identical branches, and coming up with an alternate diff form which removes the sed form from the mix, and makes this "safer" (i.e. it returns a result (namely, the most recent commit) even when you compare master to master):
As a .git-config line:
[alias]
    oldest-ancestor = !zsh -c 'diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1' -
From the shell:
git config --global alias.oldest-ancestor '!zsh -c '\''diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1'\'' -'
So, in my test tree (which was unavailable for a while, sorry; it's back), that now works on both master and topic (giving commits G and B, respectively). Thanks again, liori, for the alternate form.

So, that's what I [and liori] came up with. It seems to work for me. It also allows an additional couple of aliases that might prove handy:
git config --global alias.branchdiff '!sh -c "git diff `git oldest-ancestor`.."'
git config --global alias.branchlog '!sh -c "git log `git oldest-ancestor`.."'
Happy git-ing!
shareimprove this answer
3 
Thanks lindes, the shell option is great for situations where you want to find the branch point of a long running maintenance branch. When you are looking for a revision that might be a thousand commits in the past, the visual options really isn't going to cut it. *8') –  Mark Booth Apr 2 '12 at 15:47
3 
In your third method you depend on that the context will show the first unchanged line. This won't happen in certain edge cases or if you happen to have slightly different requirements (e.g. I need only the one of the histories be --first-parent, and I am using this method in a script that might sometimes use the same branches on both sides). I found it safer to use diff's if-then-else mode and erase changed/deleted lines from its output instead of counting on having big enough context., by: diff --old-line-format='' --new-line-format='' <(git rev-list …) <(git rev-list …)|head -1. –  liori Oct 5 '12 at 14:17
16 
Nowadays there is git merge-base --fork-point ... –  Jakub Narębski Dec 8 '13 at 14:08
2 
diff -U1 <(git rev-list --first-parent topic) <(git rev-list --first-parent master) | tail -1 . By forcing diff context to have only one line, you don't need to grep/sed through it. – Alexander Bird Dec 12 '14 at 22:13
2 
@JakubNarębski @lindes --fork-point is based on the reflog, so it will only work if you made the changes locally. Even then, the reflog entries could have expired. It's useful but not reliable at all. –  DanielJun 19 at 23:49
You may be looking for git merge-base:
git merge-base finds best common ancestor(s) between two commits to use in a three-way merge. One common ancestor is better than another common ancestor if the latter is an ancestor of the former. A common ancestor that does not have any better common ancestor is a best common ancestor, i.e. a merge base. Note that there can be more than one merge base for a pair of commits.
shareimprove this answer
6 
Note also the --all option to "git merge-base" –  Jakub Narębski Oct 6 '09 at 21:49
6 
This doesn't answer the original question, but most people asking the much simpler question for which this is the answer :) –  FelipeC Apr 23 '12 at 23:19
2 
he said he didn't wan't the result of git merge-base –  Tom Tanner Mar 20 '13 at 17:31
5 
@TomTanner: I just looked at the question history and the original question was edited to include that note about git merge-base five hours after my answer was posted (probably in response to my answer). Nevertheless, I will leave this answer as is because it may still be useful for somebody else who finds this question via search. –  Greg Hewgill Mar 20 '13 at 18:24
6 
Nowadays there is git merge-base --fork-point ... –  Jakub Narębski Dec 8 '13 at 14:07
I've used git rev-list for this sort of thing. For example,
$ git rev-list --boundary branch-a...master | grep ^- | cut -c2-
will spit out the branch point. Now, it's not perfect; since you've merged master into branch A a couple of times, that'll split out a couple possible branch points (basically, the original branch point and then each point at which you merged master into branch A). However, it should at least narrow down the possibilities.
I've added that command to my aliases in ~/.gitconfig as:
[alias]
    diverges = !sh -c 'git rev-list --boundary $1...$2 | grep ^- | cut -c2-'
so I can call it as:
$ git diverges branch-a master