This  package (now registered) exports  a single  macro @usingmerge  which differs from
using in that it “merges” the exported definitions automatically.
The wish for this started in
this thread.
At  the time I was very new to Julia  and did not think I could do anything
myself about the problem. Two years later, knowing better Julia, I realized
I could do something. Here it is.
I introduce the problem with an example.
In  my Gapjm  package (a  port of  some GAP  libraries to Julia) I have a
function  invariants which computes the invariants of a finite reflection
group.  However when  I use  BenchmarkTools to  debug for  performance my
package, I have the following problem:
julia> G= # some group...
julia> invariants(G)
WARNING: both Gapjm and BenchmarkTools export "invariants"; uses of it in module Main must be qualified
ERROR: UndefVarError: invariants not defined
Stacktrace:
 [1] top-level scope at REPL[4]:1
 [2] eval(::Module, ::Any) at ./boot.jl:331
 [3] eval_user_input(::Any, ::REPL.REPLBackend) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:86
 [4] run_backend(::REPL.REPLBackend) at /home/jmichel/.julia/packages/Revise/kqqw8/src/Revise.jl:1163
 [5] top-level scope at none:0
This  is  annoying!  I  do  not  want  to  have to qualify every call to my
function  invariants just  because I  am timing  my code!  What can I do?
Well, first I could just import the methods I am using in BenchmarkTools:
julia> using BenchmarkTools: @btime
Actually,  every exported name  from BenchmarkTools, except invariants,
does not conflict with my code:
julia> names(BenchmarkTools)
30-element Array{Symbol,1}:
 Symbol("@ballocated")
 Symbol("@belapsed")
 Symbol("@benchmark")
 Symbol("@benchmarkable")
 Symbol("@btime")
 Symbol("@tagged")
 :BenchmarkGroup
 :BenchmarkTools
 :addgroup!
 :allocs
 :gctime
 :improvements
 :invariants
 :isimprovement
 :isinvariant
 :isregression
 :judge
 :leaves
 :loadparams!
 :mean
 :median
 :memory
 :params
 :ratio
 :regressions
 :rmskew
 :rmskew!
 :trim
 :tune!
 :warmup
so I can do:
julia> using BenchmarkTools: @ballocated, @belapsed, @benchmark, @benchmarkable, @btime, @tagged, BenchmarkGroup, BenchmarkTools, addgroup!, allocs, gctime, improvements, isimprovement, isinvariant, isregression, judge, leaves, loadparams!, mean, median, memory, params, ratio, regressions, rmskew, rmskew!, trim, tune!,
 warmup
Still no conflict. Can I go further and do something even for invariants?
Well, I have one method for invariants in my package:
invariants(a::Group, args...)
while BenchmarkTools has four:
invariants(group::BenchmarkGroup)
invariants(x)
invariants(f, group::BenchmarkGroup)
invariants(f, x)
Even though some of these last methods apply to Any, they do not conflict
with  my method  (since at  least one  of the  arguments of  my method, the
first,  is qualified with my type Group), so  I can use them also by just
defining:
invariants(group::BenchmarkGroup) = BenchmarkTools.invariants(group)
invariants(x) = BenchmarkTools.invariants(x)
invariants(f, group::BenchmarkGroup) = BenchmarkTools.invariants(f, group)
invariants(f, x) = BenchmarkTools.invariants(f, x)
The  last thing to do is  make the docstring of BenchmarkTools.invariants
accessible to the help of invariants. It happens it has no docstring, but
if it had one I must do (this adds to the doc of invariants):
@doc (@doc BenchmarkTools.invariants) invariants
I  call  the  end  result  of  the  above  process  merging  the  package
BenchmarkTools  with  my  current  package.  What  I  announce  here is a
macro  @usingmerge  which  does  all  the  above automatically. If you do
julia> using UsingMerge
julia> @usingmerge BenchmarkTools
The  function determines conflicting method names in the package and merges
them as above, and does using of the non-conflicting names.
Just like for using you can usingmerge only some of the names of the
package
julia> @usingmerge BenchmarkTools: invariants, ratio
The macro @usingmerge has two optional arguments
julia> @usingmerge reexport BenchmarkTools
will   reexport  all  non-conflicting  names  (a  conflicting  name  is  by
definition  already present in your environment and will be exported if you
did export it).
julia> @usingmerge verbose=true BenchmarkTools
will  print all conflicts resolved, and verbose=2 will print all executed
commands.
You will find some more information in the docstring of @usingmerge.
Since  I wrote this function,  I found that I  got the hoped for modularity
benefits in my code. For example, I have in my Gapjm.jl package modules
- 
PermsPermutations - 
CycsCyclotomic numbers (sums of complex roots of unity) - 
PolsUnivariate Laurent polynomials - 
Mvps.jlMultivariate Puiseux polynomials - 
Posets.jlPosets - 
FFields.jlFinite fields 
that I designed as independent, stand-alone packages which each can be used
without importing anything else from my package. To use them together I can
now  just using_merge each  of them instead  of writing (unpleasant) glue
code.
I  do not advocate always  replacing the semantics of  using with that of
@usingmerge,  but  I  feel  that  @usingmerge  is a nice tool for using
packages  together without having to write glue code (and without having to
modify  any of the used packages). The meaning of “pirating a type” becomes
a   little  bit  wider  in  this  context,  as  you  saw  with  the  method
invariants(y)  in BenchmarkTools: it is, I would say, polite, if any of
your  methods which has  a possibly conflicting  name uses at  least one of
your own types in its signature.
The  program only merges methods  of functions. If a  conflicting name is a
macro,  a struct or  a type, a  message is printed  and the name is not
merged.
Any  kind of feedback will be welcome. My implementation is perhaps not the
best,  as I kind  of parse the  printed output of  methods. Accessing the
internal structure of the returned object would be better but I do not know
what’s  officially accessible  in there.  If you  have any  comments on the
code, functionality or documentation please contact me.